ラベル Neovim の投稿を表示しています。 すべての投稿を表示
ラベル Neovim の投稿を表示しています。 すべての投稿を表示

AstroNvimでtelescope.nvimがエラーを吐いたとき。

Windowsの環境でAstroNvimをインストールして、Find Fileしたらtelescopeがエラーを吐いてきました。


メッセージは、
Failed to run `config` for telescope.nvim
...a/lazy/telescope.nvim/lua/telescope/extensions/init.lua:10: 'fzf' extension doesn't exist or isn't installed: ...nvim-data/lazy/

なんて感じになってます。 

~/.local/share/nvim-data/lazy/telescope-fsf-native.nvim を見ると、Makefileがあってsrcディレクトリがありますから、AstroNvimのインストール時にコンパイルしようとしてずっこけているようです。

Makefileを見てみると、libfzf.dllを作成して配置してやればよさそうなので、msys64のコンソールを起動してMakefileのあるディレクトリに移動し、make一発。buildディレクトリが作成されて、無事libfzf.dllができあがりました。ちなみに他のディレクトリにインストールする必要はなく、このbuildディレクトにあることが必要なようです。

Neovimを起動してみると上記のエラーは消えていました。めでたしめでたし。

AstroNvimをインストールしてみる。

この2年ほどVS Codeを使っていたのだけれど、編集作業はVimのほうが馴染んでるというのもあって、ふと目にしたAstroNvimの記事に触発されて、またNeovimに戻ろうかな、などと思い立ち。

AstroNvimのGetting Startedの内容に従って進めていきます。

まず、事前に必要なもの。

  • Nerd Fonts (Optional with manual intervention: See Recipes/Customizing Icons) [1]
  • Neovim v0.8+ (Not including nightly)
  • Tree-sitter CLI (Note: This is only necessary if you want to use auto_install feature with Treesitter)
  • A clipboard tool is necessary for the integration with the system clipboard (see :help clipboard-tool for supported solutions)
  • Terminal with true color support (for the default theme, otherwise it is dependent on the theme you are using) [2]

Optional Requirements:

  • ripgrep - live grep telescope search (<leader>fw)
  • lazygit - git ui toggle terminal (<leader>tl or <leader>gg)
  • go DiskUsage() - disk usage toggle terminal (<leader>tu)
  • bottom - process viewer toggle terminal (<leader>tt)
  • Python - python repl toggle terminal (<leader>tp)
  • Node - Node is needed for a lot of the LSPs, and for the node repl toggle terminal (<leader>tn)

Neovimはリリースの一番新しい0.9.4をダウンロードして展開しました。

Nerd Fontは、すべて必要な記号フォントを含んでいるとのことで、自分好みのフォントを選択します。自分は普段はMyricaM Monoを使っているので、そのASCII文字フォントのベースとなっているInconsolataに近いNoto Nerd Fontを使ってみることにします。手間がかかりそうですが、記号部分だけを手持ちのフォントにマージして使うこともできるようですから、日本語を使う際にはそちらのほうがいいかもしれません。

Tre-sitter CLIはcargoまたはnpmでインストールできるようですが、pre-builtバイナリも提供されているようなので、そちらを使ってみます。pre-builtバイナリにはexe形式のバイナリが入っていますので、これを展開したnvim/binディレクトリに配置します。

フルカラーをサポートしたターミナルは、Windows Terminalを使えばいいかと思うのでそのままで。

クリップボードツールは、Windowsの場合にはwin32yankを使うようです。これはデフォルトでneovimのアーカイブに含まれているのでそのままで。

その他のオプションでは、ripgrepは常用しているのでOK、Pythonも常用しているのでOK、あとは追追という事にします。

次に、Installationに従って、古いNeovimの設定をバックアップしておきます。

Move-Item $env:LOCALAPPDATA\nvim $env:LOCALAPPDATA\nvim.bak

ただし、$XDG_CONFIG_HOMEが設定されていると、nvimディレクトリは $HOME/.config/nvimになります。

Move-Item $env:XDG_CONFIG_HOME\nvim $env:XDG_CONFIG_HOME\nvim.bak

nvim-dataもバックアップしておきます。

Move-Item $env:LOCALAPPDATA\nvim-data $env:LOCALAPPDATA\nvim-data.bak

最後に、AstroNvimのリポジトリをクローンします。

git clone --depth 1 https://github.com/AstroNvim/AstroNvim $env:LOCALAPPDATA\nvim

ここでも、$XDG_CONFIG_HOMEが設定されている場合には変更します。

git clone --depth 1 https://github.com/AstroNvim/AstroNvim $env:XDG_CONFIG_HOME\nvim

起動してもいいのですが、とりあえず使用したいLSPとしてpyrightを、またNeovimのPythonバインディングのpynvimをインストールします。

pip install pyright pynvim

そしてWindows TerminalのPowerShellプロンプトからnvimを起動すると、いろいろと裏で設定してくれます。

一部文字が化けているので、Windows TerminalでAstroNvim専用のプロファイルを作成し、インストールしたNerd Fontを使用するように設定を変更します。

それから、ccかgccかclangかなんかのCコンパイラが見つからない、と言われるので、Visual Studioはインストールしてあるのだけれどzigというのを入れてみました。ダウンロードしたアーカイブを展開してパスを通すだけですみます。

使い方は徐々に覚えねば。


WindowsにLua 5.1をインストールしてLuarocksする。

NeovimにはLuaJITが組み込まれています。これはLua 5.1がベースになったLuaJIT 2.1.0-beta3とのこと。ちなみにLua 5.1系自体は2012年2月17日にbug-fixリリースの5.1.5が最後です。その前年の12月に5.2.0がリリースされ、その後現在のバージョンは5.4.3になっています。

Pythonはちょろっといじってきたのですが、せっかくNeovimにLuaが組み込まれているのだし、VimScriptも難しいし、テキスト加工の自動化とかもLuaでできたら楽なのかな、と思ったのでLuaに手を出してみることにしました。

ということでちょっと調べてみると、Lua 5.1では文字列はbyte列として扱う、ということで、たとえばコマンドプロンプトでLuaインタプリタを起動し、string.len("あいうえお")とすると、
  • CP932環境では 10
  • CP65001環境では 5
です。一方Neovim(encoding=utf-8)で:lua print(string.len('あいうえお'))すると15が返ってきます。

ちょっとやってみただけなので間違ってたり環境依存だったり勘違いだったりするのかもしれませんが、まあそんな感じで一筋縄では行かなそうだし、本当に文字エンコーディングの問題は魂に刻み込まれた呪いのようです。

Windows 11が出るよ、と言われて、全部Unicodeになるの?と思ったらやっぱりならないみたいだし、この呪いはもはや「with 文字エンコーディング」として付き合っていかないとなのでしょうか。

閑話休題 それはさておき

調べてみると、Lua 5.1でも使えるutf8ライブラリがあるようです。starwindg/luautf8は、5.3のビルトインのものと互換性があるようで、これを使うのが一番良さそうです。ところがこれは LuaRocks を利用してインストールする形になっているので、Lua + LuaRocks が必要です。
 

Lua 5.1のインストール

ともかく、Luaをインストールしてしまいましょう。といっても、最新の5.4系ではなく、Neovimと同じ5.1系を選びます。具体的には最終版の5.1.5。

Lua DownloadページのToolsのところに、LuaBinariesというリンクがあるのでそこに飛びます。すると、[05/May/2014]のところに Lua 5.1.5 - Release 1 というリンクがあるのでそこをクリックします。
そこにある Tools Executables に実行形式が、Windows Libraries にDLLがあります。

使用しているNeovimは64bitビルドなので、ここでは lua-5.1.5_Win64_bin.zip を選びます。が!ここで注意なのですが、bin.zipのほうはVC+2005でコンパイルされています。そのためランタイムも必要になり、ちょっとめんどくさいです。

また、LuaRocks を動作させるためにはヘッダーファイルが必要となるため、上記 Windows Libraries から lua-5.1.5_Win64_dll16_lib.zip もダウンロードします。
bin.zipのほうはVC+2005でコンパイルされていますが、dll16_lib.zipはVS2019でコンパイルされています。

なので、余計なランタイムをなくすためにも、ここではソースもダウンロードして、Lua 5.1.5もVS2019でコンパイルし直します。ソースはtar ballになっていて、lua-5.1.5.tar.gz からダウンロードできます。

Lua 5.1のコンパイル

ダウンロードしたtar ballをほどいたら、VS2019のNative x64 コマンドプロンプトを開き、lua-5.1.5ディレクトリに移動します。INSTALLファイルを見るとプロジェクトを自分で作ってコンパイルしなさい、とありますが、ここでは簡単に etc\luavs.bat を起動します。必要に応じて src\luaconf.h を編集しなさいともありますが、特に希望はないのでそのままで。

コンパイルが無事に終われば、lua.exe、luac.exe、lua51.dll、lua51.libができています。ここではlua51.libを c:\Apps\Lua\lib に、その他を c:\Apps\Lua\bin にコピーします。
また、lua.h、lua.hpp、luaconf.h、lualib.h、luaxlib.hを c:\Apps\Lua\include にコピーします。lua.hppは etcディレクトリにあるのでご注意。
コピーしたら c:\Apps\Lua\bin にPATHを通して動作チェックです。

LuaRocksのインストール

次にLuaRocksをインストールします。といっても、Installation instructions for Windowsに従って実行形式ファイルをコピーするだけですが。
LuaRocksのダウンロードページから、Windows all-in-one executable (64-bit)をダウンロードします。このzipファイルを開くとluarocks.exeとluarocks-admin.exeがあるので、これを先程の  c:\Apps\Lua\bin コピーします。

コピーしたら、環境変数を設定します。
  • LUA_DIR : c:\Apps\Lua
  • LUA_BINDIR : c:\Apps\Lua\bin
  • LUA_INCDIR : c:\Apps\Lua\include
  • LUA_LIBDIR : c:\Apps\Lua\lib
あるいは、以下のようにしてconfigファイルを作成しておきます。
$ luarocks --lua-version 5.1 config --global variables.LUA_DIR c:\Apps\Lua
$ luarocks --lua-version 5.1 config --global variables.LUA_BINDIR c:\Apps\Lua\bin
$ luarocks --lua-version 5.1 config --global variables.LUA_INCDIR c:\Apps\Lua\include
$ luarocks --lua-version 5.1 config --global variables.LUA_LIBDIR c:\Apps\Lua\lib

します。Luaのデフォルトのバージョンは5.3になっているようで、5.1を利用する場合には --lua-version オプションが必要です。見落としているかもしれませんが、どうもデフォルトで5.1に固定するような設定はなさそうです。

luautf8のコンパイル

次はluautf8のコンパイルです。
これは、VS2019のx64 コマンドプロンプトを開いて、
$ luarocks --lua-version 5.1 --global install luautf8
とします。
$ luarocks --lua-version 5.1 --global install luautf8
Installing https://luarocks.org/luautf8-0.1.3-1.src.rock

luautf8 0.1.3-1 depends on lua >= 5.1 (5.1-1 provided by VM)
cl /nologo /MD /O2 -c -Folutf8lib.obj -Ic:\Apps\Lua\include lutf8lib.c
lutf8lib.c
link -dll -def:lua-utf8.def -out:lua-utf8.dll c:\Apps\Lua\lib/lua51.lib lutf8lib.obj
Microsoft (R) Incremental Linker Version 14.29.30133.0
Copyright (C) Microsoft Corporation.  All rights reserved.

   ライブラリ lua-utf8.lib とオブジェクト lua-utf8.exp を作成中
luautf8 0.1.3-1 is now installed in C:\Users\kats\AppData\Roaming/luarocks (license: MIT)
ちょっと深い場所に出力されていますが、ここでできた lua-utf8.dll をc:\Apps\Lua\bin にコピー、また Neovim から使うには c:\Apps\Neovim\bin にコピーすれば require で参照できます。

Lua 5.3の標準ライブラリと同様に使うために、lua-utf8 を utf8 として参照できるようにします。
> utf8 = require 'lua-utf8'
> print(utf8.reverse('あいうえお'))
おいうえあ
ただ、コマンドプロンプトとかCP932な環境なので今ひとつな感じ。Neovimだけならなんとかなるかしら。

pyls_msがなくなった。

deopleteのソースをJediからLSPに変更する。で、Microsoft Python Language ServerをNeovimから使えるようにしてみたんだけれど、:call dein#update()してみたら、エラーが出てしまいました。:messageしてみると以下のような出力が。

[dein] Error occurred while executing hook: nvim-lspconfig
[dein] Vim(lua):E5108: Error executing lua [string ":lua"]:3: attempt to index field 'pyls_ms' (a nil value)
Lua が pyls_ms を読み込もうとしたんだけれど値が nil でした、ってことです。

え、もしや、と思って検索すると、https://github.com/neovim/nvim-lspconfig/issues/1073で、Python3で使っていると Error 134を出してクラッシュする、というようなことが書いてあります。

それに対して、pyls_msはpylance/pyrightに引き継がれていてMicrosoftはメンテナンスを放棄しているので、pyrightかpylspに切り替えることを推奨します、とのこと。
pyls_ms is borderline abandoned by microsoft (in favor of pylance/pyright), I would recommend switching to pyright or pylsp (`pyls is also abandoned) I'll probably remove pyls_ms shortly. It's not a bug in the built-in client (which this repo is not, this repo is just the basic settings we send to the language servers), it's likely a bug in pyls_ms that will never be fixed
ということで、pyls_ms.luaはすでに削除されてしまっていたのでした。実際、たしかに時々LSPによる補完が効かないことがあって、なんでかなぁと思ったり、NeovimはおろかChromeとか起動しているすべてのアプリを巻き込んでクラッシュしたりということもあったので、潮時なのかもしれません。ということで候補なのですが…。

pylspことPython LSP ServerはJediをエンジンとして利用しているので、せっかくJediを離れてpyls_msにしたのにまた戻ることになります。補完速度的にも若干遅い気がしますし。

pyrightはpyls_msと同じMicrosoftから提供されていますが、使用するためにはNode.jsを別途インストールする必要があるようです。

仕方ないので、Node.jsの現行推奨版である14.17.3-x64 LTSをインストールします。ただ、Chocolateyを含むビルドツールも必要に応じてインストールする、というオプションはチェックをしないでおきます。PythonもVisual Studio 2019もインストールしてあるし。

インストールが終了したら、新規にコマンドプロンプトを開いて動作を確認します。
C:\Users\kats$ node --version
v14.17.3

C:\Users\kats$ npm --version
6.14.13
動くようなのでpyrightをインストールします。
C:\Users\kats$ npm install -g pyright
C:\Users\kats\AppData\Roaming\npm\pyright -> C:\Users\kats\AppData\Roaming\npm\node_modules\pyright\index.js
C:\Users\kats\AppData\Roaming\npm\pyright-langserver -> C:\Users\kats\AppData\Roaming\npm\node_modules\pyright\langserver.index.js
+ pyright@1.1.158
added 1 package from 1 contributor in 1.015s
pyrightを起動してみると、
C:\Users\kats$ pyright
No configuration file found.
No pyproject.toml file found.
stubPath C:\Users\kats\typings is not a valid directory.
Assuming Python platform Windows
Searching for source files
Auto-excluding C:\Users\kats\.cache\dein\.cache\init.vim\.dein\test\test-files\python\with_virtualenv\env
Auto-excluding C:\Users\kats\.cache\dein\repos\github.com\dense-analysis\ale\test\test-files\python\with_virtualenv\env
Skipping recursive symlink "C:\Users\kats\AppData\Local\Application Data" -> "C:\Users\kats\AppData\Local"
Skipping broken link "C:\Users\kats\AppData\Local\ElevatedDiagnostics"
Auto-excluding C:\Users\kats\Projects\JupyterLab
Auto-excluding C:\Users\kats\work
Found 11346 source files
Emptying type cache to avoid heap overflow. Heap size used: 1537MB
Emptying type cache to avoid heap overflow. Heap size used: 1823MB
Emptying type cache to avoid heap overflow. Heap size used: 2108MB
Emptying type cache to avoid heap overflow. Heap size used: 2381MB
Emptying type cache to avoid heap overflow. Heap size used: 1538MB
Emptying type cache to avoid heap overflow. Heap size used: 1734MB
なにやらカレントディレクトリ以下のすべての*.pyファイルを検索してキャッシュしているようです。

それはさておき。

Neovim側では、これまで使用していたpyls_msの設定を削除して、pyrightの設定をdein.tomlに追加します。
nvim_lsp.pyright.setup{
}
ここに記入する設定は、CONFIG.md#pyrightに説明されています。が、基本的にはパスさえ通っていれば特に設定の必要はなさそうです。

dein.tomlを保存してからNeovimを起動し直すと、こころなしかpyls_msのときよりも起動が早いようです。遅延発火(lazy)はしていないので、これはNode.jsをインストールしてまで導入したかいがあったかもしれません。

日本語検索を「かな漢字変換」を通さずにやる。

ローカルなライブラリの検索で、日本語ファイル名が数千になってきているのです。
そうなるとあいうえお順で(というかエクスプローラーの一覧から)目視で探すのは限界だし、ディレクトリツリーを順番に見ていくのも大変なので、mktexlsrのようにファイル名のデータベースを作っておいてそのデータベースから探すのが早そう、ということでPythonでls-R作成スクリプトと検索スクリプトを作りました。

検索文字列はreモジュールで正規表現検索するので、一部だけでも適当に検索してくれます。ものすごく便利で自画自賛なんですが、検索したいファイル名(の一部)を入力するときにいちいち「かな漢字変換」をオン・オフするのは面倒だな、と思って、そういえばローマ字入力で日本語文書を検索できるヤツがあったな、と思い出し……。

NamazuじゃなくてKakasiじゃなくてMeCabじゃなくてなんだっけ……とグーグル先生にお尋ねして。

名前が思い出せなかったので、そういえばVimを2chブラウザにするヤツを作っていた人がいて、その人がなんかやってたような、なんだっけ、としばらく考えて検索して、"Chalice"をようやく思い出して。そこから "Migemo" にやっとたどり着きました。
Migemo自体はRubyで記述されているようで、かつすでにメンテされていないようです。もったいない。でも自分はRubyはわからないので、KaoriYaのKoronさんがCに移植されたC/Migemoを見てみようか、と。

Cで実装されてDLLにされているなら、Pythonから呼び出すのもできそうだし、Neovimにも組み込むことができそうです。まあ、後者は追々というとこで、とりあえずPythonから呼び出してローマ字で日本語検索!をやれれば楽ができるかなということで、ぼちぼちいじってみようと思います。

C/MigemoはGitHubで公開されていましたので、これをクローンして作業開始です。

README_j.txtには以下のようにVisualC++でのビルド方法が書かれています。
  (Windows + VisualC++)
  次のコマンドでRelease/内にmigemo.dllとcmigemo.exeが作成されます。
    > nmake msvc
  必要な外部プログラム、ネットワーク接続が揃っていれば
    > nmake msvc-dict
  で辞書ファイルをビルドできます。migemo.dswをVC++6.0で開き、ビルドする方法も
  あります。以上が終了すれば次のコマンドでテストプログラムが動作します。
    > .\build\cmigemo -d dict/migemo-dict
現在の環境はVisualC++を含んだVisualStudio 2019なので、そのままビルドと思いきややっぱりエラーが出ました。

幸い\compile\vs2003.slnファイルがあったので、それをVS2019で開くとそのままソリューションを変換してくれて一応プロジェクトは開けました。

そのままF6キーでビルドすると、"afxres.h"がインクルードできない、というエラーが出てビルドできません。
ぐぐってみると、"winres.h"に書き換えるといいよ、ということだったので仰せに従い無事ビルド終了。ついでにプロジェクトにx64ビルドも追加してこちらもビルド。一応どちらもDebugビルドにしておきました。


お次は辞書ファイルの生成ですが、Makefileを追いかけるとnkfではなくiconvやqkcを使っていました。qkcは今どうしてるんだろう…。

それはさておき。

現状ではnkfを使っているので、nmakeと同じことをコマンドプロンプトからそのままやりました。
dictディレクトリで、
$ for %i in (base-dict,SKK-JISYO.L,*.dat) do (
More? nkf -w %i > utf-8.d\%i
More? )
$ for %i in (base-dict,SKK-JISYO.L,*.dat) do (
More? nkf -e %i > euc-jp.d\%i
More? )
で辞書の文字コード変換は終了。


早速テストしてみます。cmigemoディレクトリに移動して、
$ compile\vs2003\x64\Debug\CMigemo.exe
migemo_open("./dict/migemo-dict")=000002AB8059C640
clock()=0.128000
QUERY: aho
PATTERN: (アホ|アホ|信天翁|阿[房呆]|あほ|aho|aho)
QUERY: clean
PATTERN: (clean|ク(レン(ザー|ジング)|リ(ンナップ|ー(ン|ナー|ニング)))|c(ェア[ンノネヌニナ]|ェア[ンノネヌニナ]|ぇあ[んのねぬにな]|lean))
QUERY: nihongo
PATTERN: (ニホンゴ|ニホンゴ|日本(語|極道史|合成ゴム)|にほんご|nihongo|nihongo)
QUERY: 日本語
PATTERN: 日本語
QUERY:
QUERY:
おお、返り値がそのまま正規表現として利用できるようなパターンになっています。なにげに信天翁(アホウドリ)が混じっているのが点数高いです。そして、かな漢字変換で日本語を食わせるとそのまま返ってきます。

これは結構使えるのでは……。 辞書の指定とかエンコードとか出力形式とかはどうなんだろうと見てみると、
$ compile\vs2003\x64\Debug\CMigemo.exe -h
cmigemo - C/Migemo Library 1.3 Driver

USAGE: compile\vs2003\x64\Debug\CMigemo.exe [OPTIONS]

OPTIONS:
  -d --dict <dict>      Use a file <dict> for dictionary.
  -s --subdict <dict>   Sub dictionary files. (MAX 8 times)
  -q --quiet            Show no message except results.
  -v --vim              Use vim style regexp.
  -e --emacs            Use emacs style regexp.
  -n --nonewline        Don't use newline match.
  -w --word <word>      Expand a <word> and soon exit.
  -h --help             Show this message.
また、辞書を指定するとそのエンコードで結果が返ってくるようです。
$ compile\vs2003\x64\Debug\CMigemo.exe -w aho
(アホ|アホ|信天翁|阿[房呆]|あほ|aho|aho)

$ compile\vs2003\x64\Debug\CMigemo.exe -d dict\utf-8.d\base-dict -w aho
(繧「繝斈菫。螟ゥ鄙-髦ソ[謌ソ蜻・|縺ゅ⊇|・・ス茨ス楯aho)

$ compile\vs2003\x64\Debug\CMigemo.exe -d dict\utf-8.d\base-dict -w aho | nkf -s
(アホ|信天翁|阿[房呆]|あほ|aho|aho)

$ compile\vs2003\x64\Debug\CMigemo.exe -d dict\euc-jp.d\base-dict -w aho
(・「・ロ|ソョナキイァ|ー、[ヒシハ|、「、ロ|」皀陬・aho)

$ compile\vs2003\x64\Debug\CMigemo.exe -d dict\euc-jp.d\base-dict -w aho | nkf -s
(アホ|信天翁|阿[房呆]|あほ|aho|aho)
受け取り側に都合のよいエンコードの辞書を使えば良さそうです。

Neovim+vimtex+TeXLive 2021+SumatraPDFでTeX環境を作ってみる。

NeovimでのPythonの環境をLSPに変更したので、vimtexが使っている補完ソースもLSPにしてみます。

TeX用Language Serverのセットアップ

LSはtexlab/Relaseからバイナリをダウンロードします。
実行形式ファイルが1つだけなので、インストールはこのtexlab.exec:/Apps/languageServerにコピーするだけです。

次にdein.tomlのnvim-lspconfigのところにLSに関する設定を追加します。
[[plugins]]
# A collection of common configurations for Neovim's built-in language server client.
repo = 'neovim/nvim-lspconfig'
hook_add = '''
set runtimepath+=~/.cache/dein/repos/github.com/neovim/nvim-lspconfig/lua
lua << EOF
local nvim_lsp = require('lspconfig')

nvim_lsp.pyls_ms.setup{
    cmd = { "dotnet", "exec", "c:/Apps/languageServer/Microsoft.Python.LanguageServer.dll" },
	init_options = {
	  analysisUpdates = true,
	  asyncStartup = true,
	}
}
nvim_lsp.texlab.setup{
    cmd = { "c:/Apps/languageServer/texlab.exe" },
}
EOF
'''
一応これだけでLSPを利用した補完はできるようになります。 ただし、ALEを使っている場合にはALEとLSPで二重にチェックされたりするらしいので、問題がある場合にはその部分で変更が必要です。ALEの設定部分で let g:ale_disable_lsp = 1と設定するといいらしいです。

vimtexとSumatraPDFの連携

vimtexでコンパイルまでできるんだから、逆順検索もちゃんとできるようにします。

まず、逆順検索(inverse search)はRPCを使ってNeovimとSumatraPDFがやりとりします。具体的には、SumatraPDF側でクリックされた行情報をRPCでNeovimに送ります。Neovim側はRPCで受け取ったコマンドを実行して、PDFでのクリックされた行のソースにジャンプします。

ということでNeovimを外部から、コントロールするためのneovim-remoteが必要になります。
$ pip install neovim-remote
するとnvrというコマンドが利用できるようになります。

nvrでは予めサーバの場所を指定しておく必要があります。NeovimのRPCの場合には、\\.\pipe\nvim-1234-0というようにパイプが作成されるので、それを利用する必要がありますが、パイプ名は毎回異なります。
一方、SumatraPDFでは逆順検索コマンドで利用するためにサーバの場所を知りたいのですが、そのためにはNeovimと通信できないとわかりません。毎回手動で設定するのも大変ですし、現実的ではありません。

そこで、起動時にNeovimが作成するRPCサーバとは別に、SumatraPDF専用のRPCサーバを起動してそこと通信させればうまくいきます。

Neovim側で
if has('win32')
	call serverstart('\\.\pipe\nvim-vimtex-1234')
endif

let g:vimtex_view_general_options
			\ = '-reuse-instance'
			\ . ' -forward-search @tex @line @pdf'
			\ . ' -inverse-search "nvr --servername ' . '\\.\nvim-vimtex-1234'
			\ . ' --remote-send \"\%lG\""'
などとvimtexの設定時にRPCサーバを起動し、このパイプ名をSumatraPDFの逆順検索コマンドに指定してやればよいのです。
nvr --servername \\.\pipe\nvim-vimtex-1234 --remote-send "%lG"
これでPDFで行をクリックするとNeovim側で対応する行にジャンプします。 ・・・でも順方向がちゃんと動かない・・・。

deopleteのソースをJediからLSPに変更する。

ついでにvimtexまわりの変更も行います。

JediからLanguage Serverへ

約2年前にNeovim+vimtex+TeXLive2018でTeX環境を作ってみる。というエントリを書いたのですが、ここへきて Neovim の 0.5.0 がぼちぼち(予定では6月15日)にリリースされるということで、Nightly ビルドを持ってきて使っています。

もともとは Python プログラミングの補完などのためにdeoplete-jediを使っていましたが、jediよりも速いという話もあってLSPを利用した入力サポートへの変更を行いました。

Python用のLanguage Server(LS)はいくつかありますが、VS Codeと併用するならばVS Codeで使用されている Pylance のベースとなっているMicrosoft Python Language Serverが、一番違和感なく使えるのではないかということでこれを候補にしました。
他にもpalantir/python-language-serverhttps://github.com/python-lsp/python-lsp-serverにありますが、こちらはエンジン?にJediを利用するということで、deoplete-jediで使っているのと変わらないためにパスしています。また、NeovimをVS Codeのような感じにするというCoC(Conquer of Completion)というフレームワークがあり、そのプラグインで使うという方法も調べてみましたが、こちらはNode.jsで動くということで、Node.jsを使う予定はないのでこれもパスしました。

結果、構成としては以下のようになります。
  • Neovim + deoplete を利用する
  • deoplete からLSを利用するため、deoplete-lsp プラグインを利用する
  • LSPとしてはMicrosoft Python Language Server(pyls_ms)を使用する
  • pyls_msの設定を簡単に行うため、nvim-lspconfigを使用する

pyls_msをビルドする

Microsoft Python Language ServerはC#で記述されているので、.NETのビルド環境が必要です。うちではVisual Studio 2019がインストールされているので、コマンドプロンプトから以下のコマンドを叩けばビルドできます。
$ git clone https://github.com/Microsoft/python-language-server.git
$ cd python-language-server/src/LanguageServer/Impl
$ dotnet build -c Release
ビルドが正常に終了したらpython-language-server/output/binディレクトリにある全ファイルをc:/Apps/languageServerディレクトリにコピーします。

deoplete-lspを導入する

dein.tomlを編集し、deoplete-jediを削除したあとで以下の記述を追加します。
[[plugins]]
# LSP Completion source for deoplete
repo = 'deoplete-plugins/deoplete-lsp'
hook_add = '''
let g:deoplete#lsp#handler_enabled=1
let g:deoplete#lsp#use_icons_for_candidates=0

'''

nvim-lspconfigを導入する

続けて以下の記述を同じくdein.tomlに追加します。
[[plugins]]
# A collection of common configurations for Neovim's built-in language server client.
repo = 'neovim/nvim-lspconfig'
hook_add = '''
set runtimepath+=~/.cache/dein/repos/github.com/neovim/nvim-lspconfig/lua
lua << EOF
local nvim_lsp = require('lspconfig')

nvim_lsp.pyls_ms.setup{
    cmd = { "dotnet", "exec", "c:/Apps/languageServer/Microsoft.Python.LanguageServer.dll" },
	init_options = {
	  analysisUpdates = true,
	  asyncStartup = true,
	}
}
EOF
'''
一応このとき、dein_lazy.tomlでのdeopleteの設定は以下のようになります。
[[plugins]]
# Dark powered asynchronous completion framework for Neovim / Vim8
# require: python3
repo = 'Shougo/deoplete.nvim'
depends = 'context_filetype.vim'
on_i = 1
hook_post_source = '''
  call deoplete#enable()
  source $XDG_CONFIG_HOME/nvim/rc/deoplete.rc.vim
'''

起動する

設定が終わったらインストールとキャッシュの作り直しをしておきます。
:UpdateRemotePlugins
:call dein#update()
:call dein#recache_runtimepath()
Neovimを再起動してPythonファイルを編集し、補完候補の右側に[LSP]と出てくればちゃんと動いています。

vimtexがfiletypeで起動しない。その2

Neovim で\(\rm\TeX\)ファイルを編集するときに vimtex が正常に動作していなかった件ですが、どうやら原因がわかりました。

Neovim で編集する\(\rm\TeX\)ファイルを読み込むときにパス名に日本語が含まれていると、vimtex が以下のようなエラーを出します。

Error detected while processing function vimtex#init[4]..50_init_state[1]..vimtex#state#init[1]..52_get_main[24]..52_file_is_main:
line   10:
E484: Can't open file C:\Users\kats\Google_Drive\サーバードキュメント\Setting_up_Manjaro_Linux.tex

Neovim 自体ではこのファイルは正常に開けますが、vimtex が読み込むときにエラーを起こしているようです。具体的にどの文字が悪さしているのかは「ダメ文字」で検索してみると、どうやら「ー」が該当するようです。

これを回避するための方法は2つあります。

  1. ダメ文字を使わないこと。一番確実なのは日本語を使わないことでしょう。
  2. 「ベータ: ワールドワイド言語サポートでUnicode UTF-8を使用(U)」を使ってシステムのエンコーディングを UTF-8 にすること。

他にも vimtex 側で対処してもらうとかありそうですが、UTF-8 にすればダメ文字の呪いから開放されるので、その場合にはファイル名やパス名に日本語が容赦なく使用できます。

LaTeXでのダッシュ。

\(\rm\LaTeX\)でのダッシュで、vimtexではチェックに使っているchktexが"Wrong length of dash may have been used. (8)"という警告を出してきます。

w0rp/aleでこれを抑制するには、

let g:ale_tex_chktex_options = "-n 8"

などとすれば8のチェックを無視してくれるようになるのですが、そもそもこのダッシュの使い方をきちんと理解していないのでまとめです。

ダッシュ類の使い方は言語によって異なるので、ここではあくまで英語を取り上げます。

When should I use an em-dash, an en-dash, and a hyphen?に詳細が説明されていますが、

  • "-" : ハイフン。2つ以上の単語の間をつなぐのに使う。
  • "--" : en-dash。範囲を示すのに使う。"3--7"など。
  • "---" : em-dash。文中のカッコと同様の使い方---たとえばこんな風に---をする。

だそうです。

vimtexがfiletypeで起動しない。

Neovim-Qtとlervag/vimtexで\(\rm\LaTeX\)文書をドラッグ&ドロップするとちゃんと動いていたのに、起動しなくなってしまいました。

検索してみたところ、vimtexのhelpになにか書いてありました。

COMMENT ON INTERNAL TEX PLUGIN                        *vimtex-comment-internal*

Vim ships with some LaTeX support out of the box. In particular, it provides
good syntax highlighting (|ft-tex-syntax|), indentation (see the source file
$VIMRUNTIME/indent/tex.vim for the documentation), and some sensible options
(|ft-tex-plugin|).

When |vimtex| is active, it will be used as the main |ftplugin|. It will
define the same set of sensible settings as the internal plugin. However,
|vimtex| does not provide its own syntax, instead it adds a few minor
improvements to |ft-tex-syntax|, see |vimtex-syntax|. |vimtex| also provides its
own indentation plugin, see |vimtex-indent|.

Vim will generally autodetect filetypes automatically. In most cases this
works as expected, however, in some cases it will detect a file with the `tex`
suffix as a |plaintex|. To prevent this, one may set the option
|g:tex_flavor| in ones `vimrc` file, that is: >

  let g:tex_flavor = 'latex'

Vimはすぐに使えるようにいくつかのLaTeXサポート機能が同梱されています。とりわけ、すぐれたシンタックスハイライト(ft-tex-syntax)、インデンテーション、気の利いたオプション(ft-tex-plugin)を提供しています。

vimtexがアクティブならば、メインのファイルタイププラグインとして使用されます。これは内部プラグインの気の利いた設定と同等のことを定義します。けれども、vimtexは独自のシンタックスを提供する代わりに、ft-tex-syntaxにいくつかの些細な改良を加えています。vimtexはまた独自のインデンテーションを提供しています(vimtex-indent)。

Vimは一般的にファイルタイプを自動的に検出します。ほとんどの場合これは期待通りに動作しますが、いくつかの場合には"tex"拡張子のファイルタイプをplaintexと検出してしまいます。これを防ぐには、g:tex_flavorオプションを設定すると良いかもしれません。

とのことです。
ところがこれをやってみても、どうにもうまく検出してくれません。もしかしたらvimtexのオプション設定でどこかミスがあって、それがvimtexモードになるのを阻害しているのかもしれませんが…。

vimtexの便利な機能が使えないのは結構困るのですが、とりあえず保存するたびにコンパイルしてくれるようにしたいので、以下のようにしました。

latexmk -pvc -view=none %1
というバッチファイルを作成し、ルートtexファイル(\includeなどでいくつかのファイルを読み込んでいる場合の一番親ファイル)を食わせると、子ファイルに変更があったときでも自動でコンパイルを始めてくれます。

それからこんな記事を見つけました。
Writing LaTeX in Neovim with Vimtex
あとで読んでみようと思います。

Neovim+vimtexでのテキストアライン。

テキストアライン、あるいは桁揃えですが、Vim/Noevimでもいくつかのプラグインがあります。Align とか vim-easy-align とか。

ただ、自分で使ってみた感じでは godlygeek/tabular が使いやすかったので、これの使い方をメモです。

tabularでは、範囲指定したうえでどの文字を桁揃えに使用するかを正規表現で指定します。

たとえば現在行から5行分を、'&'文字で桁揃えしたい場合には、
:.,+5Tab /&
とします。この場合、各カラムは左寄せです。

','で区切られた各カラムを中央寄せにし、前後に最低1文字以上のスペースを入れる場合には、
:Tab /,/c1
とします。

','で区切られた各カラムを右寄せにし、','との間に1文字の空白を入れる場合には、
:Tab /,/r1
とします。

桁揃えの指定は正規表現なので、
:Tab /[,|&]
などとすれば ',''|''&'の3つの文字を桁区切りに指定できます。

vimtexのfoldカスタマイズ。

lervag/vimtexで、foldingを有効にしてみたら文書の見通しがよくなったので、自分的カスタマイズとその他のメモなど。

\section や \subsection、あるいは itemize や description、lstlisting などの部分を折りたたむことができれば、文書の構成がより把握しやすくなるし、編集もしやすくなってくるので、なにを折りたたむかの設定やキーマップなどをざっくりとまとめます。

まず vimtex の構成として、折りたたみ動作は fold.vim がやっているようです。その中のvimtex#fold#init_buffer() を見ると、ある程度の初期化がされているのがわかります。つらつら見ていくとどういう構造で折りたたもうとしているのかがおおよそわかります。

折りたたみはデフォルトでは無効になっているので、これを有効にしてやればまずは折りたたみができるようになります。

let g:vimtex_fold_enabled = 1

g:vimtex_fold_manual = 1にすると、デフォルトで折りたたみ処理を行わない状態でファイルを開きます。大きいファイルをよく扱うような場合に、ファイル読み込みが遅くなるのを回避します。このとき、キーマップ zx と zX がリマップされます。

折りたたみの操作は以下の通り。詳細については :h fold を参照。
  • zo カーソルの下の折りたたみを1段階開く。カウントが与えられればカウント数分開く。
  • zO カーソルの下の折りたたみをすべて開く。
  • zc カーソルの下の折りたたみを1段階閉じる。カウントが与えられればカウント数分閉じる。
  • zC カーソルの下の折りたたみをすべて閉じる。
  • za カーソルの下の折りたたみが閉じていれば開く。開いていれば閉じて、foldenableをセットする。
  • zA カーソルの下の折りたたみが閉じていれば再帰的に開く。開いていれば再帰的に閉じて、foldenableをセットする。
  • zm 折りたたみをより閉じる。foldenableをセットする。
  • zM すべての折りたたみを閉じる。foldenableをセットする。
  • zr 折りたたみをより開く。
  • zR すべての折りたたみを開く。
なにを折りたたむかは g:vimtex_fold_types で指定します。基本的には、g:vimtex_fold_types_defaultsで設定されている既定値を必要に応じて上書きします。定義は辞書の形式で行い、{キー:値}で定義していきます。

vimtex のヘルプファイルからキー(と値)の解説から一部引用して加筆翻訳しておきます。
  • 'preamble'
    プリアンブルを折りたたむかどうか。
    • { 'enabled' : 0/1 } -- 0:折りたたまない 1:折りたたむ
  • 'comments'
    複数行のコメントを折りたたむかどうか。デフォルトは無効。
    • { 'enabled' : 0/1 } -- 0:折りたたまない 1:折りたたむ
  • 'envs'
    環境を折りたたむかどうか。'document'環境は折り畳まれない。
    • { 'blacklist' : [] } -- 折りたたまない環境のリスト。正規表現が使える。
    • { 'whitelist' : [] } -- 折りたたむ環境のリスト。正規表現が使える。
  • 'envs_options'
    環境のオプション(複数行などの長いもの)を折りたたむかどうか。
    • { 'enabled' : 0/1 } -- 0:折りたたまない 1:折りたたむ
  • 'sections'
    section とパートを折りたたむかどうか。以下のキーがある。
    • { 'parse_levels' : 0/1} -- vimtex-toc で表示されるような感じでレベルを解析して折りたたむかどうか。デフォルトは 0。有効にするとリソースを食うし遅くなる。
    • { 'sections' : [] } -- 折りたたみする section のリスト。リストには正規表現が使える。デフォルトは [ 'part', 'chapter', 'section', 'subsection', 'subsubsection' ]
    • { 'parts' : [] } -- 折りたたみをするパートのリスト。リストには正規表現が使える。デフォルトは [ 'appendix', 'frontmatter', 'mainmatter', 'backmatter' ]
あとの詳細はヘルプファイル参照。 とりあえず以下の設定を使います。
let g:vimtex_fold_types = {
  \  'envs' : {
  \   'whitelist' : ['table', 'lstlisting'],
  \  },
  \  'comments' : {'enabled' : 1},
  \}

let g:vimtex_fold_enabled = 1

NetBSDでlibuvがコンパイルできない件。

自分用メモです。

NetBSD-8 で Neovim の master ブランチをビルドしようとしたら、libuv で
~/build/neovim/.deps/build/src/libuv/src/unix/thread.c:222:22: error: ‘PTHREAD_STACK_MIN’ undeclared (first use in this function)
     if (stack_size < PTHREAD_STACK_MIN)
                      ^
というエラーが出て、コンパイルできませんでした。 ちょっと調べてみると、/usr/include/limits.h
/*
 * These are the correct names, defined in terms of the above
 * except for PTHREAD_KEYS_MAX which is bigger than standard
 * mandated minimum value _POSIX_THREAD_KEYS_MAX.
 */
#define PTHREAD_DESTRUCTOR_ITERATIONS   _POSIX_THREAD_DESTRUCTOR_ITERATIONS
#define PTHREAD_KEYS_MAX                256
/* Not yet: PTHREAD_STACK_MIN */
#define PTHREAD_THREADS_MAX             _POSIX_THREAD_THREADS_MAX
という部分があり、確かに定義されていません。 さらに調べてみると、NetBSD の tech-userlevel メーリングリストで2014年にPTHREAD_STACK_MINというメールが投げられていました。そこでの結論は、 PTHREAD_STACK_MINの代わりにsysconf(_SC_THREAD_STACK_MIN)を使ったほうが安全、ということのようです。 一方 libuv のほうでは、今年の4月に Do not use PTHREAD_STACK_MIN unconditionally for the unix target #2252というのが出ており、結果として「定義されていれば使用する」という形に落ち着いたようです。途中、GNU じゃない FreeBSD とか NetBSD は libuv はサポートせんよ、みたいな投稿もありましたが。

ともあれ、現状では Neovim の CMake では libuv-1.26.0(2019年2月11日リリース)を使用しているようで、1.29.0 では上記の変更が反映されているようなので、そのうち修正なしでコンパイルできるようになるでしょう。

Neovim でのコンパイルにおいては、最初にある thread.c に #2252 のパッチを当てればいいかと思います。

NeovimをVisual Studio 2019でコンパイルする。

以前にNeovimをVisual Studio 2017でコンパイルする。を書いていますが、ちょうど1年経ったことでもあるので、アップデートしてみます。
前提条件ですが、うちでは c:/Apps/Neovim 以下にインストールしていますので、新規ビルドは c:/Apps/Neovim-new にインストールしてから最後にディレクトリ名を変更する形にします。

Neovimをコンパイルする

CMakeのおかげもあって、ものすごく楽になっています。
以前にあった C4819 警告(データの損失を防ぐために、ファイルを Unicode 形式で保存してください。)は出ますが、これは 「ベータ: ワールドワイド言語サポートでUnicode UTF-8を使用(U)」をセットしておくか、Windowsのシステムロケールを「英語(米国)」に変更しておくことで回避できます。お勧めは後者のシステムロケールの変更です。
$ git clone https://github.com/neovim/neovim
$ cd neovim
neovim$ make CMAKE_BUILD_TYPE=Release CMAKE_INSTALL_PREFIX=c:/Apps/Neovim-new
で依存ライブラリまで含めてすべてビルドしてくれます。
ビルドが終わったら
neovim$ make install
です。

Neovim-Qtをコンパイルする

equalsraf/neovim-qtは活発な開発という段階は終わって、API への対応があるくらいでほぼ安定ということなのでしょう、最後のコミットも3ヶ月以上前です。
ただ、Neovim の Windows バイナリに同梱されている Neovim-Qt は 32bit 版なので、好みの問題でしょうが 64bit 版をコンパイルします。

README.mdには
$ mkdir build
$ cd build
$ cmake -G "Visual Studio 14" -DCMAKE_BUILD_TYPE=Release ..
$ cmake --build . --config Release --target install
とありますが、自分の環境ではこれだけではコンパイルできないのでまとめです。

Qt5 は c:\Apps\Qt\ 以下にインストールしています。バージョンは 5.12.2 で、C:\Apps\Qt\5.12.2\msvc2017_64\binをパスに追加しています。これがないと WinDeployQt.exe を見つけられなくてエラーになります。

また CMake は 3.14.4 でパスを通しています。
$ git clone https://github.com/equalsraf/neovim-qt
$ cd neovim-qt
neovim-qt$ mkdir build
$ cd build
build$ set CMAKE_PREFIX_PATH=C:/Apps/Qt/5.12.2/msvc2017_64/lib/cmake/Qt5Core;C:/Apps/Qt/5.12.2/msvc2017_64/lib/cmake/Qt5Gui;C:/Apps/Qt/5.12.2/msvc2017_64/lib/cmake/Qt5Svg;C:/Apps/Qt/5.12.2/msvc2017_64/lib/cmake/Qt5Network;C:/Apps/Qt/5.12.2/msvc2017_64/lib/cmake/Qt5Widgets;C:/Apps/Qt/5.12.2/msvc2017_64/lib/cmake/Qt5Test
build$ cmake -G "Visual Studio 16" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=c:/Apps/Neovim-new ..
build$ cmake --build . --config Release
ここで msgpack-cpp-3.0.1 が C2220 エラーを出してビルドがエラー終了します。なので CMakeLists.txt にパッチを当てます。
neovim-qt$ diff -rub third-party/CMakeLists.txt.orig third-party/CMakeLists.txt
--- third-party/CMakeLists.txt.orig     Sat May 18 09:56:59 2019
+++ third-party/CMakeLists.txt  Sat May 18 09:53:11 2019
@@ -13,17 +13,17 @@
 set(MSGPACK_URL https://github.com/msgpack/msgpack-c/archive/cpp-${MSGPACK_VERSION}.tar.gz)
 set(MSGPACK_SHA256 1b834ab0b5b41da1dbfb96dd4a673f6de7e79dbd7f212f45a553ff9cc54abf3b)

-message(STATUS "Downloading Msgpack...")
-set(MSGPACK_TARBALL msgpack-${MSGPACK_VERSION}.tar.gz)
-file(DOWNLOAD ${MSGPACK_URL} ${CMAKE_CURRENT_SOURCE_DIR}/${MSGPACK_TARBALL}
-       INACTIVITY_TIMEOUT 30
-       EXPECTED_HASH SHA256=${MSGPACK_SHA256})
-execute_process(COMMAND ${CMAKE_COMMAND} -E tar xfz ${MSGPACK_TARBALL}
-       WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-       RESULT_VARIABLE rv)
-if(NOT rv EQUAL 0)
-  message(FATAL_ERROR "Failed to extract ${MSGPACK_TARBALL}")
-endif()
+#message(STATUS "Downloading Msgpack...")
+#set(MSGPACK_TARBALL msgpack-${MSGPACK_VERSION}.tar.gz)
+#file(DOWNLOAD ${MSGPACK_URL} ${CMAKE_CURRENT_SOURCE_DIR}/${MSGPACK_TARBALL}
+#      INACTIVITY_TIMEOUT 30
+#      EXPECTED_HASH SHA256=${MSGPACK_SHA256})
+#execute_process(COMMAND ${CMAKE_COMMAND} -E tar xfz ${MSGPACK_TARBALL}
+#      WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+#      RESULT_VARIABLE rv)
+#if(NOT rv EQUAL 0)
+#  message(FATAL_ERROR "Failed to extract ${MSGPACK_TARBALL}")
+#endif()

 set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR})
 set(MSGPACK_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/msgpack-c-cpp-${MSGPACK_VERSION}/)
上のパッチを当てておかないと、修正しても上書きされてしまいます。
neovim-qt$ diff -rub third-party/msgpack-c-cpp-3.0.1/CMakeLists.txt.orig third-party/msgpack-c-cpp-3.0.1/CMakeLists.txt
--- third-party/msgpack-c-cpp-3.0.1/CMakeLists.txt.orig Sat May 18 09:57:13 2019
+++ third-party/msgpack-c-cpp-3.0.1/CMakeLists.txt      Sat May 18 09:53:42 2019
@@ -251,9 +251,9 @@

 IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
     IF (CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
-        STRING(REGEX REPLACE "/W[0-4]" "/W3 /WX" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+        STRING(REGEX REPLACE "/W[0-4]" "/W3" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
     ELSE ()
-        SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /WX")
+        SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3")
     ENDIF ()
 ENDIF ()
また、ソースの方では test/tst_neovimconnector.cpp が文字コードの関係でエラーになります。
neovim-qt$ diff -rub test/tst_neovimconnector.cpp.orig test/tst_neovimconnector.cpp
--- test/tst_neovimconnector.cpp.orig   Sat May 18 10:40:47 2019
+++ test/tst_neovimconnector.cpp        Sat May 18 12:00:12 2019
@@ -40,7 +40,7 @@
                NeovimConnector *c = NeovimConnector::spawn({"-u", "NONE"});

                // This will print a warning, but should succeed
-               QString s = "ç日本語";
+               QString s = "nihongo";
                QByteArray bytes = c->encode(s);
                QCOMPARE(c->decode(bytes), s);

そうしたらビルド&インストールします。Neovimよりもあとにインストールすることで、32bit バイナリも上書きしてくれます。
build$ cmake --build . --config Release --target install
実際には本来不要なものまでインストールされますが、気になる場合には本家のビルドとファイルを比べて削除すればよいでしょう。

ホームディレクトリのドットファイルを整理する。

UNIX 系の OS で、ちょっと悩ましいのは $HOME(ホームディレクトリ)にドットファイルが増えてしまうことです。

ls -a すると表示されるリストの8割以上がドットファイルとか、もう許して下さいな感じです。

% ls -a
.              .aliases~                        .dbus        .hgignore   .profile         .xinitrc              .zshrc~    __pycache__
..             .bash_history                    .dir_colors  .hgignore~  .python_history  .xprofile             Desktop    bin
.ICEauthority  .bash_logout                     .dmrc        .hgrc       .ssh             .xsession-errors      Documents  build
.Xauthority    .bash_profile                    .esd_auth    .hgrc~      .texlive         .xsession-errors.old  Downloads  work
.Xclients      .bashrc                          .gem         .lesshst    .thumbnails      .zcompdump            Music
.Xmodmap       .cache                           .gkrellm2    .local      .thunderbird     .zsh                  Pictures
.Xmodmap.orig  .chrome-remote-desktop-session   .gnupg       .mozc       .vim             .zshenv               Public
.Xmodmap~      .chrome-remote-desktop-session~  .gvimrc      .mozilla    .vimrc           .zshenv~              Templates
.aliases       .config                          .hg          .pki        .wget-hsts       .zshrc                Videos

編集した結果バックアップファイルやらコピーを残してるのやらありますが、まあざっとこんな感じ。もうちょっと整理して数を減らしたいところです。
このときに頼りになるのが XDG Base Directory Specification。それを規格から実装に照らして説明してくれているのがこちら

なので一つ一つやっていきます。環境は Manjaro Linux XFCE 版なので、他のディストロは適当に読み替えてください。

システム

システム側であらかじめ設定されているのは以下の環境変数です。
XDG_SESSION_ID=c5
XDG_RUNTIME_DIR=/run/user/1000
XDG_SESSION_TYPE=tty
XDG_SESSION_CLASS=user
また、ユーザ側で設定しておきたいのは以下の環境変数です。
XDG_CONFIG_HOME=$HOME/.config
XDG_CACHE_HOME=$HOME/.cache
XDG_DATA_HOME=$HOME/.local/share
XDG_RUNTIME_DIR はユーザごとに設定される /var/run みたいなものです。デフォルトではユーザIDが振られています。必要なら設定すればよいでしょう。
それとは別に、/etc/xdg に設定ファイルがいくつか置かれています。ただしこれらは ssh ログイン時などには読み込まれないようなので、ここでは置いておきます。
ここでは、お仕着せでシステムワイドに設定する方向で進めていきます。

bash

まずは標準の shell の bash。Manjaro の場合には、次の順序で読み込まれるようです。bash -l -v で確認しました。つまりログインシェルの場合。
  1. /etc/profile
  2. /etc/profile.d/*.sh
    /etc/profile から呼ばれる。アルファベット順に読み込まれる。アプリケーションごとに必要な設定はここ。ロケールもここ。
  3. /etc/bash.bashrc
    /etc/profile から呼ばれる。システムワイドの bash 設定を行う。プロンプトや $TERM の設定はここ。
  4. /usr/share/bash-completion/bash_completion
    もしあれば読み込まれる。Manjaro にはない。
  5. $HOME/.bash_profile
    $HOME/.bashrc を source しているだけ。
  6. $HOME/.bashrc
    ユーザの環境変数とか alias とかいろいろと設定する。
  7. プロンプトが表示されて bash 起動完了。
  8. $HOME/.bash_logout
    ログアウト時に読み込まれる。何もしていない。
  9. /etc/bash.bash_logout
    ログアウト時に読み込まれる。何もしていない。
bash の場合にはユーザごとのドットファイルはハードコードされているようなので、ドットファイル類を .config/bash に移動することは(現状では)できません。ただ、他のアプリケーションのための設定は必要なので、ここでは /etc/profile.d/xdgenv.sh あたりで XDG ユーザ変数を設定するようにすればよいでしょう。そうすることで他の shell からも source することができます。
/etc/profile.d/xdgenv.sh:
# Set user variables based on XDG Base Directory Specification.
#

export XDG_CONFIG_HOME=$HOME/.config
export XDG_CACHE_HOME=$HOME/.cache
export XDG_DATA_HOME=$HOME/.local/share

zsh

zsh では環境変数 ZDOTDIR が設定されているとそこを見に行きます。
  1. /etc/zsh/zshenv
    本来は /etc/zshenv を読みにいく(manページの説明)ようだが、Manjaro では /etc/zsh/zshenv を読みにいく。
  2. $ZDOTDIR/.zshenv
    環境変数 ZDOTDIR が指定されていれば $ZDOTDIR/.zshenv を、指定されていなければ $HOME/.zshenv を読む。
  3. /etc/zsh/zprofile
    Manjaro では /etc/zsh/zprofile の中身は emulate sh -c 'source /etc/profile' となっていて、/etc/profile を読み込む。/etc/profile の読み込むものは bash と同じ。
  4. $ZDOTDIR/.zprofile
    ZDOTDIR が指定されていなければ $HOME/.zprofile を読み込む。
  5. /etc/zsh/zshrc
  6. $ZDOTDIR/.zshrc
  7. /etc/zsh/zlogin
    ログインシェルの場合に読み込まれる。
  8. $ZDOTDIR/.zlogin
    ログインシェルの場合に読み込まれる。
  9. プロンプトが表示されて bash 起動完了。
  10. $ZDOTDIR/.zlogout
    ログアウト時に読み込まれる。何もしていない。
  11. /etc/zsh/zlogout
    ログアウト時に読み込まれる。何もしていない。
ということなので、bash のところで /etc/profile.d/xdgenv.sh を作成していれば、XDG* はそこで設定されます。また、/etc/zsh/zshenv があれば一番最初に読み込まれるので、ZDOTDIR をそこで設定すればいいのですが、ZDOTDIR=$XDG_CONFIG_HOME/zsh とする必要があるため、二重に読み込むことになりますが以下のようにします。
# /etc/zsh/zshenv
# set ZDOTDIR respecting XDG Base Directory Specification
#

emulate sh -c 'source /etc/profile'
export ZDOTDIR=$XDG_CONFIG_HOME/zsh
また、標準ではコマンドヒストリは $HOME/.zsh/histfile に保存されますが、これを $XDG_CACHE_HOME/zsh/history に変更します。コマンドヒストリはユーザ設定なので、これは $XDG_CONFIG_HOME/zsh/.zshrc で設定し直します。
$XDG_CONFIG_HOME/zsh/.zshrc:
HISTFILE=$XDG_CACHE_HOME/zsh/hisotry
zstyle :compinstall filename '$ZDOTDIR/.zshrc'
これで $HOME から zsh 関連のドットファイルは削除できます。

git

0d94427eから XDG_CONFIG_HOME に対応しているので、$XDG_CONFIG_HOME/git/config を使います。

Neovim

Neovim は最初から XDG Base Directory Specification に沿うように作られているので、$XDG_CONFIG_HOME/nvim を利用すれば問題ありません。
ここで、vim からも同じ設定を使えるように init.vim などを記述しておくと、nvim でも vim でも同じように使えます。

vim

vimはちょっとややこしいです。前述の ArchLinux の Wiki に書いてあるように、.vimrc などは基本的にハードコードされています。が、別途 VIMINIT=":source $XDG_CONFIG_HOME"/vim/vimrcを shell の設定時に行っておけば、vim の起動時に $VIMINIT を参照してくれます。
なので $ZDOTDIR/.zshenv に設定しておきます。ここでは vim と nvim の設定を共通にすることを考えているので、あえて $XDG_CONFIG_HOME/nvim/vimrc にします。ただし、undodir などが一緒になると問題があるかもしれないので、そこは別にしておきます。Manjaro の場合には vim は標準ではインストールされていなくて、ex および vi が標準なので、あえて vim をインストールせずに alias vim=nvim するのもアリかもしれません。
# .zshenv

PATH1=$HOME/bin
export PATH=$PATH:$PATH1

export QT_SELECT=5
export GTK_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx
export QT_IM_MODULE=fcitx

# better yaourt colors
export YAOURT_COLORS="nb=1:pkg=1:ver=1;32:lver=1;45:installed=1;42:grp=1;34:od=1;41;
5:votes=1;44:dsc=0:other=1;35"

# env for locate updatedb for local files.
export PRUNEPATHS="`echo $HOME/.cache/[a-ce-z]*`"
export PRUNEPATHS="`find $HOME -name \".hg\" -printf \"%p \"` $PRUNEPATHS"
export PRUNEPATHS="$HOME/.mozilla $HOME/.dbus $HOME/.thumbnails $HOME/.thunderbird $
PRUNEPATHS"
export LOCATE_PATH=$XDG_CACHE_HOME/mlocate.db

export VIMINIT=":source $XDG_CONFIG_HOME"/nvim/vimrc
また、vimrc は以下の内容にします。
" vim:set et ts=2 sts=2 sw=2 tw=0 fenc=utf-8:
" _vimrc : initialization file for Vim.
" just source init.vim for commonnization.
"
" Modified: 9 Apr 2018
"
source $XDG_CONFIG_HOME/nvim/init.vim

" mswin.vim maps those keys when gui=yes.
" this is terrible and should be unmapped.
if has('gui')
  unmap <C-f>
  iunmap <C-f>
  cunmap <C-f>

  unmap <C-h>
  iunmap <C-h>
  cunmap <C-h>
endif

mercurial

$HOME/.hgrc は $XDG_CONFIG_HOME/hg/hgrc に移動することができます。が、.hgignore はそのディレクトリ以下の ignore ファイルを指定しているため、移動できません。また .hg ディレクトリはリポジトリのため、移動できません。

その他

.ICEauthority

libice が作成するファイルですが、Use XDG base directory instead of $HOME for .ICEauthorityで議論され、パッチがあげられ、2019年3月25日に push されているので、いずれマージされるでしょう。
それまでは触らないでおくか、export ICEAUTHORITY="$XDG_RUNTIME_DIR"/ICEauthority を /etc/zsh/zshenv あたりに入れておけばよいでしょう。ただ、環境変数がやたら増えるのも困りものですから、ここでは放置しておきます。

.Xauthority

同上です。export XAUTHORITY="$XDG_RUNTIME_DIR"/Xauthority

.Xmodmap

対応策はなさそうです。

.dircolors

source "$(dircolors "$XDG_CONFIG_HOME"/dircolors)" を $ZDOTDIR/.zshenv あたりに入れておきます。bash のほうは $HOME/.bashrc のdircolors に関する部分の変更が必要です。

.mozc

移動できません。ソースを見ましたが、XDG_CONFIG_HOME を参照している部分はありませんでした。

.mozilla(firefox)

$XDG_CONFIG_HOME/mozilla と $XDG_CACHE_HOME/mozilla と $XDG_DATA_HOME/mozilla がある場合にはそちらを使うようです。
なので、以下のようにします。
$ mkdir .config/mozilla
$ mkdir .cache/mozilla
$ mkdir .local/share/mozilla
$ chmod 700 .config/mozilla .cache/mozilla .local/share/mozilla

.python_history

Python がインタラクティブモードで起動されると readlline が作成するようです。今のところ移動できません。

.texlive

ハードコードされているようで変更できません。

.thumbnails

$XDG_CACHE_HOME/thumbnails/ があればそちらを使うようです。

.thunderbird

ハードコードされているようで変更できません。

.xinitrc

基本的には DesktopManager(lightdmやgdmなど)を使っていれば xinit を呼ぶことはないので不要なはずですが、export XINITRC="$XDG_CONFIG_HOME"/X11/xinitrc を指定することで xinit は参照してくれます。

.gnupg

export GNUPGHOME="$XDG_CONFIG_HOME"/gnupgすることで参照してくれます。

LaTeXコマンドのあとには空白を入れる。

Neovim+vimtex+TeXLive2018でTeX環境を作ってみる。では、すでに ALE をインストールしていたので、自動的に chktex による構文チェックが走っていました。

chktex 自体は TeXLive 2018 に含まれているので、ALE がデフォルトで使用するようになっているようです。

で、\(\rm \LaTeX\) 文書中で \LaTeX と入力すると、Command terminated with space. (1) などというヒントが表示されました。エラーではないですが、\(\rm \LaTeX\)に関する記事などを書いているとそこらじゅうで出まくります。

ちなみに \(\rm \LaTeX\)は、Mathjax を使って部分的に\(\rm \LaTeX\)として処理させています。記法は、\(\rm \LaTeX\) という形で埋め込んでいます。

話を戻して、ALE (chktex)の警告の件ですが、\LaTeX␣ はコマンドとして解釈されるので、通常は地の文ではその次に空白が来ませんから、次の単語とくっつきます。\(\rm \TeX\)文書中で対処する場合には、\LaTeX␣\LaTeX\␣とします。日本語文書の場合でも末尾にスペースを入れて次の文字とは離します。
なので、
$$
\verb|\LaTeX is a typesetter.| \Longrightarrow {\rm \LaTeX is\ a\ typesetter.}\\
\verb|\LaTeX\ is a typesetter.| \Longrightarrow {\rm \LaTeX\ is\ a\ typesetter.}\\
\verb|\LaTeX\ は組版。| \Longrightarrow {\rm \LaTeX\ は組版。}
$$
となるため、やっぱり \(\rm \TeX\)文書中で対処すべきですね。

Neovim+vimtex+TeXLive2018でTeX環境を作ってみる。

以前に Neovim で \(\rm \LaTeX\) の環境構築をやって、Neovim では Vim にあった "--remote-*" コマンドラインオプションが削除されてしまったために、vimtex での inverse search ができずに挫折していました。
SyncTeX対応のPDFビューワ。でちょっと触れていますが、それを解決するために neovim-remote という Python モジュールを使って、Python インタフェース側から解決しましょうかというのがあったのですが、結局うまく行ってませんでした。

ぼちぼちあれから1年経つので、どうなってるのかな、と。もっとも Visual Studio Code + TeXLive でかなりいい感じの環境が手軽に構築できるので、あとは日本語入力のON/OFFをうまいことやってくれないかな、とかエディタ周りの使用感によって左右されるのかなとは思いますが。

まず、2019年4月5日現在、Neovim v0.4.0-529 には '--remote-*' 系オプションは実装されていないようです。これはすなわち、neovim-remote を使う必要がある、ということでしょう。現在の neovim-remote はバージョン 2.1.7 になっています。

'--remote-*' 系オプションに関する議論は、vimtex の Add support for neovim #262 あたりから始まって、neovim の restore --remote (+clientserver) #1750あたりに展開し、[WIP] Added clientserver --remote #8326あたりで作業に取り掛かっている方がいらっしゃるという状況です。

Neovim(というか nvim)は起動するとサーバソケット(Windowsの場合には名前付きパイプ)をオープンします。:echo v:servername
\\.\pipe\nvim-12345-0'
というような値を返してきます。

neovim-remote は、 'nvr' という実行形式ファイルを使って Neovimのサーバソケットと通信します。vimtex においてこの通信が本当に必要なのは、SyncTeX を利用するときだけです。Neovim から \(\rm \LaTeX\) を起動してコンパイルし、SumatraPDF で表示するだけならばぶっちゃけ不要です。
が、生成された PDF を見て、レイアウトがおかしかったりタイポがあったりしたときに、PDF の該当箇所をクリックすることで TeX 文書の該当箇所にジャンプしてくれる SyncTeX はとても便利です。

というような点を踏まえて、設定してみます。

まずは vimtex の wiki から Neovim のところに最初の設定が書いてあります。
let g:vimtex_compiler_progname = 'nvr'

次に vimtex の doc で、
let g:vimtex_view_general_viewer = 'SumatraPDF'
let g:vimtex_view_general_options
  \ = '-reuse-instance -forward-search @tex @line @pdf'
  \ . ' -inverse-search "gvim --servername ' . v:servername
  \ . ' --remote-send \"^^'
  \ . ':drop \%f^:\%l^:normal\! zzzv^'
  \ . ':execute ''drop '' . fnameescape(''\%f'')^'
  \ . ':\%l^:normal\! zzzv^'
  \ . ':call remote_foreground('''.v:servername.''')^^\""'

となっているところを参照します。これは inverse-search に関する設定で、SumatraPDF に渡すオプションです。逆に言えば、これを設定する前にコマンドプロンプトから SumatraPDF をオプション付きで起動して動作するかどうかを確かめることができます。

なので手順を踏んでやってみます。

まず、あらかじめ TeX ファイルをコンパイルして PDF と SyncTeXファイルを作っておきます。ページ数などがある程度あったほうがいいので、ちょっと長めのファイルを用意します。ここでは TeXLiveに含まれている pxchfon.tex を使います。このパッケージは日本語のフォントを変更するときに必ずお世話になるものですから、PDFを手元に用意しておくのも無駄にはなりませんし。

適当なディレクトリを用意して、pxchfon.tex をダウンロードします。ここでは手動で PDF を作成するので、コマンドプロンプトを開いてそのディレクトリに移動し、latexmk pxchfon と実行します。
pxchfon.tex は uplatex で組版するようになっていますから、必要があれば latexmkrc を別途作成しておきます。
ちなみにうちのは以下のような感じです。
$latex = 'uplatex %O -kanji=utf8 -no-guess-input-enc -synctex=1 -interaction=nonstopmode %S';
$pdflatex = 'pdflatex %O -synctex=1 -interaction=nonstopmode %S';
$lualatex = 'lualatex -cmdx %O -synctex=1 -interaction=nonstopmode %S';
$xelatex = 'xelatex %O -synctex=1 -interaction=nonstopmode %S';
$biber = 'biber %O --bblencoding=utf8 -u -U --output_safechars %B';
$bibtex = 'upbibtex %O %B';
$makeindex = 'upmendex %O -o %D %S';
$dvipdf = 'dvipdfmx %O -o %D %S';
$dvips = 'dvips %O -z -f %S | convbkmk -u > %D';
$ps2pdf = 'ps2pdf.exe %O %S %D';
$pdf_mode = 3;
$pdf_previewer = '"C:/Program Files/SumatraPDF/SumatraPDF.exe" -reuse-instance';

この内容を、%USERPROFILE%\.config\latexmk\latexmkrc に保存しておきます。正確に言えば、latexmk は XDG Base Directory に準拠していますので、$XDG_CONFIG_HOME/latexmk/latexmkrc ということになります。うちでは他のプログラムで参照するものもあるので、環境変数 XDG_CONFIG_HOME を %USERPROFILE%/.config に設定しています。

TeXLive が適切にインストールされて設定されていれば、上記の latexmk で pxchfon.pdf と pxchfon.synctex.gz ができているはずです。

次に、SumatraPDF にパスが通っているかを確認します。Neovim からビューワを起動するときに、パスが通っていないと起動できません。コマンドプロンプトで sumatrapdf pxchfon.pdf として起動します。
また、nvr にパスが通っているかどうかも確認します。コマンドプロンプトで nvr として確認します。パスが通っていなければ Python の Scripts にもパスを通します。

次に、Neovim で pxchfon.tex を開きます。SyncTex の動作確認だけですので vimtex は組み込んでいなくても構いません。

Neovim で :echo v:servername してパイプ名を調べます。ここでは \\.\pipe\nvim-15280-0 という名前が返ってきましたのでこれを控えておきます。

SumatraPDFのオプション設定で、逆順検索コマンドラインを設定します。逆順というよりも逆方向だとは思いますが。
nvr --servername \\.\pipe\nvim-15280-0 --remote-send "%lG"


ここまでやったら、PDFの適当なところでダブルクリックしてみます。
ジャンプしましたか? うちではちゃんとジャンプできました。え? ていうかほんとにジャンプできました。おお、すごい。

ということは、Neovim の vimtex から latexmk でコンパイルして、SumatraPDF で PDF 表示させて、PDF から SyncTeX でソースの該当箇所に飛ぶことができるということですね。

ちなみに上記の nvr でパイプに送りつけているコマンドは、%lG (%l はダブルクリックした箇所の行番号で、Gコマンドで%l行に移動する、というだけ)です。

ということなので、あとは適切に .toml を書いておけばOKとなります。
[[plugins]]
# vimtex: LaTeX documentation support plugin
repo = 'lervag/vimtex'
depends = ['deoplete.nvim']
on_ft = 'tex'
hook_source='''
  if filereadable(expand('~/.config/nvim/vimtex-local.vim'))
    source ~/.config/nvim/vimtex-local.vim
  endif
'''
hook_post_source='''
  let $NVIM_LISTEN_ADDRESS=v:servername
'''
を dein_lazy.toml に、
"scriptencoding utf-8
" vim:set ts=4 sts=2 sw=2 tw=0 fenc=utf-8:

" vimtexの設定
let g:vimtex_view_general_viewer = 'SumatraPDF'
let g:vimtex_compiler_latexmk = {
  \ 'background' : 0,
  \ 'build_dir' : '',
  \ 'continuous' : 0,
  \ 'callback' : 1,
  \ 'executable' : 'latexmk',
  \ 'options' : [
  \   '-verbose',
  \   '-file-line-error',
  \   '-synctex=1',
  \   '-interaction=nonstopmode',
  \ ],
  \}

if has('nvim')
  " if running on Neovim
  let g:vimtex_compiler_progname = 'nvr'
  let g:vimtex_view_general_options
 \ = '-reuse-instance'
 \ . ' -forward-search @tex @line @pdf'
 \ . ' -inverse-search "nvr --servername ' . v:servername
 \ . ' --remote-send \"\%lG\""'
 \ . ' -console'
  let s:sumatra_args='-reuse-instance -inverse-search "nvr --servername ' . v:servername
   \ . ' --remote-send \"\%lG\""'
else
  if has('win32')
 " if running on Vim
 let g:vimtex_compiler_progname = 'c:/Apps/vim80/gvim'
 let g:vimtex_view_general_options = '-reuse-instance -forward-search @tex @line @pdf -inverse-search "c:\Apps\vim80\gvim --remote-silent +\%l \%f " -console'
 let s:sumatra_args='-reuse-instance -inverse-search "gvim --servername ' . v:servername
   \ . ' --remote-send \"\%lG\""'
  endif
endif

function Kick_SumatraPDF()
  execute '!start SumatraPDF' s:sumatra_args expand("%:t:r").'.pdf'
endfunction

nnoremap  :call Kick_SumatraPDF()
~/.config/nvim/vimtex-local.vim に保存します。
これで F8 キーでビューワが開いて逆方向検索もできるようになりました。

ここでは、以前にちゃんとビューワが開けなかったために明示的に Kick_SumatraPDF() という関数を作ってそれを実行させていますが、本来は <localleader>lv (ただし localleader は "\")でビューワが開くマッピングになっています。

簡単にまとめると、
  • \ll : vimtex-compile(コンパイルの実行)
  • \lv : vimtex-view(PDFの表示)
  • \lk : vimtex-stop (コンパイルの中止。ただしWindowsでは効かない)
  • \le : vimtex-errors(quickfixウィンドウの表示)
  • \lg : vimtex-status(コンパイルの状態を表示)
  • \lc : vimtex-clean(中間ファイル類を削除)
  • \li : vimtex-info(vimtexの状態を表示)
などとなっています。

余談ですが、TeXLive 2019 は今月末にリリースのようですね。

Neovim+ALEでclang-formatを使う。

好みの問題にはなりますが、プログラムコードを書く場合に、コードの整形を自動で行いたいという向きもあるでしょう。Python なら autopep8 とか。

C言語だと clang-format というものがありますがこれは Clang の配布物に含まれていて、別に Clang はいらないけど clang-format を使いたいという場合には 1GB を超えるツールをまるごとインストールするのは大変です。LLVM のダウンロードページにあるインストーラは Clang と LLD、その他の LLVM ツール類がやまほど含まれていて、巨大なパッケージになっています。

でも実際にほしいのは clang-format.exe だけ。ということで、ダウンロードしたインストーラを 7zip で展開してみたら、LLVM のツリー構造がそのまま展開されたので、そこから bin/clang-format.exe だけを抜き出して、パスの通った場所にコピーします。

興味本位でその他のファイルも眺めてみると、clang-format.exe の他に、clang-tidy.exe や clang-refactor.exe、clang-include-fixer.exe などというものもあります。使い方はよくわかりませんが、名前だけ見ると便利そう。ですが、たとえば include-fixer は参照が足りていない #include を構成してくれるというもので、不要な #include を見てくれるわけではないようです。

とりあえず、ALE で clang-format.exe を使って自動整形できればいいので、clang-format.exe だけに着目します。

余談ですが、Visual Studio 2017 や 2019 では、clang-format.exe を同梱しているようです。C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\VC\vcpackagesあたりにありますが、バージョンはちょっと古いようです。

コマンドプロンプトを開いて、clang-format -version などとして動作することがわかったら、Neovim の設定をします。
現在は .toml ファイルでプラグインをロードしているので、そちらでの設定です。
[[plugins]]
## Asynchronous Lint Engine
repo = 'w0rp/ale'
hook_add='''
  let g:ale_lint_on_enter = 1
  let g:ale_lint_on_text_changed = 1
  let g:ale_fix_on_save = 1
  let g:ale_fixers = {
  \   '*': ['remove_trailing_lines', 'trim_whitespace'],
  \   'c': ['clang-format'],
  \   'cpp': ['clang-format'],
  \   'python': ['autopep8', 'isort'],
  \   'go': ['gofmt']
  \}
  let g:ale_linters = {
  \   'python': ['flake8'],
  \   'c': ['cpplint'],
  \   'cpp': ['cpplint']
  \}
  let g:ale_python_autopep8_options = '--max-line-length=99'
  let g:ale_python_flake8_options = '--max-line-length=99'
  let g:ale_virtualtext_cursor = 1
'''
自分がちょくちょく使用する言語の設定だけですが、こんな感じ。ちなみに cpplint は Python で実行されるので、利用するには pip install cpplint が必要です。

Defxを使ってみる。

vimproc.vim を使えるようにしたところで、:Denite file_rec しようとしたのですが、そういえば Denite.nvim を使ったファイラというトピックがあったような、と思い出して検索したところ、Defx.nvim という形で動くようになっていました。

説明を読むと Denite.nvim には依存していなくて、バックエンドで Python3 を動かしているようです。なので pynvim のインストールが必要です。また、:UpdateRemotePlugins のおまじないを唱えておくといいかもしれません。

Defx は Neovim から使えるファイラですが、キーマッピングはデフォルトのものがないため、自分で定義しなくてはいけないそうです。そこで、:help defxdefxを使ってみるを参考にさせていただき、Vimfiler と同様の操作ができるように設定しました。
基本的にはhjklで操作、リターンでオープンな感じですが、なかなかいいですね。

ドットディレクトリもいくつかあって、それが表示されないなと思ったら '.' で 'toggle_ignored_files' というコマンドを呼び出せるようにマップされていて、これで ~/.config などのディレクトリも表示できるようになりました。

vimproc.vimをビルドする。

deinで "call dein#update()" したらエラーがいくつもでて、こちらではいじっていないのに食い違いがあるからアップデートできないよということになったので、 "~/.cache/dein" をまるごと削除してクリーンインストールしました。

まず dein.vim をページのとおりにインストールし、次に "call dein#install()" するだけですが、vimproc.vim がエラーを吐いてきました。makeできませんよ、と。

Neovim や Vim は Visual Studio でビルドされているので、vimproc.vim の DLL も Visual Studio でビルドします。手元のバージョンは Visual Studio Community 2017 15.9.11 です。そういえば Visual Studio 2019 もリリースされましたね。

dein#install() によってソース自体はダウンロードされているので、まずは VS2017用 x64 Native Tools コマンドプロンプトを開き、"~/.cache/dein/repos/github.com/Shougo/vimproc" に移動します。

そこには "make_msvc.mak" があるので、"nmake -f make_msvc.mak" します。
$ nmake -f make_msvc.mak CPU=AMD64

Microsoft(R) Program Maintenance Utility Version 14.16.27030.1
Copyright (C) Microsoft Corporation.  All rights reserved.

make_msvc.mak(25) : fatal error U1052: ファイル 'Win32.mak' が見つかりません。
Stop.
ああ、そういえばそんなのが前にも…と思い出しました。
Win32.mak は Windows SDK 7.1A に含まれています。なので、
$ set SDK_INCLUDE_DIR=C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Include
$ nmake -f make_msvc.mak

Microsoft(R) Program Maintenance Utility Version 14.16.27030.1
Copyright (C) Microsoft Corporation.  All rights reserved.

        IF NOT EXIST src\objAMD64/nul  MKDIR src\objAMD64
        cl -Zi -Od -DDEBUG -c -DCRTAPI1=_cdecl -DCRTAPI2=_cdecl -nologo -GS -D_AMD64_=1 -DWIN64 -D_WIN64  -DWIN32 -D_WIN32 -W4 -D_WINNT -D_WIN32_WINNT=0x0500 -DNTDDI_VERSION=0x05000000 -D_WIN32_IE=0x0500 -DWINVER=0x0500  -D_MT -D_DLL -MDd  -D_NDEBUG -D_CRT_SECURE_NO_WARNINGS=1 -D_BIND_TO_CURRENT_VCLIBS_VERSION=1 /wd4100 /wd4127 /O2 -Fdsrc\  -Fosrc\objAMD64\ src\proc_w32.c
cl : コマンド ライン warning D9025 : '/Od' より '/O2' が優先されます。
proc_w32.c
c:\users\kats\.cache\dein\repos\github.com\shougo\vimproc\src\vimstack.c(286): warning C4267: '=': 'size_t' から 'unsigned int' に変換しました。データが失われているかもしれません。
src\proc_w32.c(697): warning C4018: '>=': signed と unsigned の数値を比較しようとしました。
        link /NOLOGO /DEBUG /DEBUGTYPE:cv  /INCREMENTAL:NO /NOLOGO -entry:_DllMainCRTStartup -dll kernel32.lib  ws2_32.lib mswsock.lib advapi32.lib   /OUT:lib\vimproc_win64.dll src\objAMD64/proc_w32.obj shell32.lib
   ライブラリ lib\vimproc_win64.lib とオブジェクト lib\vimproc_win64.exp を作成中
        IF EXIST lib\vimproc_win64.dll.manifest  mt -nologo -manifest lib\vimproc_win64.dll.manifest -outputresource:lib\vimproc_win64.dll;2
なにやら警告が出ていますが、気にしない。

すると、"~/.cache/dein/repos/github.com/Shougo/vimproc/lib" に DLL ファイルができているのでビルドは無事終了です。

Neovimを起動したら、:let result=vimproc#system('ls') などとしたあとで :echo result して結果が入っていれば OK です。

SWDなら3線でいいとはいうものの。

 安価で優秀なデバッグプローブはないかしら、と探したら、 Raspberry Pi Debug Probe というのがあったんですが、これは3線がにゅるんと出てるだけです。 もちろんSWDなら3線を繋げばいいのではありますが、汎用的に考えるなら5x2のリボンケーブルコネクタが欲し...