2024年12月10日火曜日

Vim の組み込み関数の結果をバッファに出力する

この記事は Vim advent calendar 2024(Adventar) の10日目の記事です。

この記事はなに?

getcellpixels() の追加を行った際に、 テストでバッファに関数の結果を出力する必要があったので、やり方を調べた。

結論

:redi @"
:echo getcellpixels()
:redi END
""p

ここでは、 :redi @" で、コマンドの出力を " レジスタへリダイレクト開始の設定をしている。

その後、 :echo getcellpixels()getcellpixels() 関数の結果を出力しているが、 先のリダイレクト設定により、その結果が " レジスタに格納される。

:redi END でリダイレクト設定を解除し、 ""p" レジスタの内容をバッファにペーストする。

こうすることで、空のバッファにペーストした際には、バッファの 3 行目にコマンドの結果が出力される。

3 行目である理由は謎。

以上。

参考資料

2024年12月6日金曜日

keyinput-delayer.vim で Vim での編集力を鍛える

この記事は Vim advent calendar 2024(Adventar) の4日目の記事です。

この記事はなに?

mikoto2000/keyinput-delayer.vim: 別名「Vimmer 養成ギプス」。 を作ったので、その宣伝です。

人はついつい「知っている方法・慣れた方法」で物事を進めてしまう。

それは Vim における編集でも同じことで、ついつい h, j, k, l での移動をしてしまいがちです。

それはなぜかというと、「キー入力のコストがとても低いから」であると私は考えました。

キー入力のコストがもっと高ければ、丁寧丁寧丁寧に操作を吟味してキー入力をすることでしょう。

例えば、帯域の狭い回線の SSH で、エコーバックがなかなか帰ってこない時、いつもより丁寧に操作をしたことはありませんか?

そんな環境を Vim 上で再現するのが mikoto2000/keyinput-delayer.vim, 別名「Vimmer 養成ギプス」です。

使い方

let g:keyinput_delayer_delay_time = "1000m" のようにディレイ時間を設定し、 keyinput_delayer#ToggleKeyInputDelay() を呼び出すことで、ディレイのあり・なしを切り替えます。

例えばディレイを 1 秒にしたとき、 10 行下に移動するために必要な時間は以下のようになります。

  • j x 10 : 10 秒
  • 10j : 3 秒

これを見て分かる通り、キーインプットのコストが非常に高くなるため、 「タイプ数を減らして編集を実現する」という意識が高くなります。

皆さんも keyinput-delayer.vim を導入して Vim のキーストロークゴルフ思考を身に着けていきましょう!

類似プラグイン

同じ目的のプラグインが存在することを vim-jp で教えていただきました。

こちらは、連続の 1 マス移動でカーソルが全く動かなくなるので、 よりストイックに鍛えたい方に向いているのではないでしょうか?

以上、 keyinput-delayer.vim の宣伝でした。

2024年12月3日火曜日

Nix で Vim をスタティックリンクビルドする。ついでにクロスコンパイルもする

この記事はなに?

mikoto2000/devcontainer.vim の ARM 対応で、 ARM 版のスタティックリンクな Vim が必要になった。

vim-jp にて「Nix ならコマンド一発でできるよ」と教えてもらったのでやってみた。

前提

  • Docker: Docker version 27.3.1, build ce12230
  • 使用イメージ: nixos/nix

Nix のリポジトリアップデート

nix-channel --update

スタティックリンクビルド

nix-build '<nixpkgs>' --cores 20 -A pkgsStatic.vim
  • --cores: make でいうところの -j オプション

aarch64 のクロスコンパイル&スタティックリンクビルド

nix-build '<nixpkgs>' --cores 20 -A pkgsCross.aarch64-multiplatform.pkgsStatic.vim

ビルドされた Vim の場所

find で探しましょう。

bash-5.2# find /nix -name vim
/nix/store/jx5d1dp77cwkarvalh1l8zvfp2ziqzlw-vim-static-aarch64-unknown-linux-musl-9.1.0787/share/vim
/nix/store/jx5d1dp77cwkarvalh1l8zvfp2ziqzlw-vim-static-aarch64-unknown-linux-musl-9.1.0787/bin/vim
/nix/store/7wkl9dji0dq6v7nmdjp1d72wd5pydqpb-vim-static-x86_64-unknown-linux-musl-9.1.0787/share/vim
/nix/store/7wkl9dji0dq6v7nmdjp1d72wd5pydqpb-vim-static-x86_64-unknown-linux-musl-9.1.0787/bin/vim
/nix/store/gnzqq5zg8r55apxa5avlb5yp0ix8qdwk-nixpkgs/nixpkgs/pkgs/applications/editors/vim
/nix/store/gnzqq5zg8r55apxa5avlb5yp0ix8qdwk-nixpkgs/nixpkgs/pkgs/test/vim
/nix/store/yzqnkb2mfzphmhv3248pw0pqh6f1mn6y-7sprarsdfz9qcd7859phvr9nvhi14mri-source/pkgs/applications/editors/vim
/nix/store/yzqnkb2mfzphmhv3248pw0pqh6f1mn6y-7sprarsdfz9qcd7859phvr9nvhi14mri-source/pkgs/test/vim

bin 下のが目的のバイナリですね。

share の方にはランタイムが入っています。

パッケージング

Vim は、ランタイムと一緒に配布しないと上手く動かないので、パッケージングを行う。 さらに、ランタイムの場所はビルド時に決め打ちされるため、 VIM 環境変数を上書きして Vim を起動するシェルスクリプトを用意し、それ経由で実行してもらうようにする。 (今回の場合は AppRun というシェルスクリプトを用意)

# aarch64 のパッケージング
cp -a /nix/store/jx5d1dp77cwkarvalh1l8zvfp2ziqzlw-vim-static-aarch64-unknown-linux-musl-9.1.0787 vim-9.1.0787-aarch64
cd vim-9.1.0787-aarch64
cat << "EOF" > ./AppRun
#!/bin/sh
CURRENT_DIR="$(dirname "$(realpath "$0")")"
export VIM="${CURRENT_DIR}/share/vim/"
exec "${CURRENT_DIR}/bin/vim" "$@"
EOF
chmod a+x ./AppRun
cd ..
tar zcfv ./vim-9.1.0787-aarch64.tar.gz vim-9.1.0787-aarch64

# aarch64 のパッケージング
cp -a /nix/store/7wkl9dji0dq6v7nmdjp1d72wd5pydqpb-vim-static-x86_64-unknown-linux-musl-9.1.0787 vim-9.1.0787-x86_64
cd vim-9.1.0787-x86_64
cat << "EOF" > ./AppRun
#!/bin/sh
CURRENT_DIR="$(dirname "$(realpath "$0")")"
export VIM="${CURRENT_DIR}/share/vim/"
exec "${CURRENT_DIR}/bin/vim" "$@"
EOF
chmod a+x ./AppRun
cd ..
tar zcfv ./vim-9.1.0787-x86_64.tar.gz ./vim-9.1.0787-x86_64

これで、「ダウンロードした tar.gz を展開して、その中の AppRun を実行すれば vim が起動する」という感じになります。

devcontainer.vim で必要なので、このスタティックリンクな Vim を mikoto2000/vim-static: Distributing a static link binary for vim/vim. で配布予定です。

以上。

参考資料