rcmdnk's blog

20210420_vimahkcaret

Vimの機能で編集時にノーマルモードとインサートモードでキャレットの形を変更する機能があります。

CLI版だとターミナルエミューレーターによって使えたり使えなかったりしますが、 GUI版だとノーマルモードだと文字にかぶる様なインジケーターで インサートモードに入ると文字の間に入るようなのになったりアンダーバーになったり。

それをvim_ahkでなんとかできないか、ということで入れてみたもの。

vim_ahk

vim_ahkはWindows上でAutoHotkeyを使ってあらゆるアプリケーション上で Vimライクな操作を実現するためのスクリプトです。

ノーマルモードやインサートモードといったモード変更をした上で JKで上下に動いたりすることができます。

キャレットサイズ

キャレットというかテキストカーソルというか。

文字を書き込む時に書き込む位置に表示される四角形のインジケーター的なやつです。

Vimではモードが変わった際に、それをわかりやすくするため、 ノーマルモードでは位置の文字に被さるようなものになり、 インサートモードでは文字の左側に細いものだったり、アンダーバーにしたりする機能があります。

WindowsやMacのアプリ版だと恐らく最初から使えると思います。

ターミナル上のVimだとターミナルエミュレーターとの兼ね合いもあるので その上で設定している人もいるかと。

それをvim_ahkでも実現したいな、というもの。

1年くらい前にIssueで出してくれたもので、確かに面白いな、と思ったもので どうにかできないかと調べてました。

Windowsの設定

調べてると、 Windows 10ではそもそもテキストカーソルを変更する設定が追加されてることに気づきました。

20210420_winsettings.jpg

この設定は上の設定画面で変更すると再起動とかしないでも即座に反映されます。

なのでこいつの値をなんとか変更してやれば良いんじゃないかと。

で、こいつを決めてるレジストリ値を見つけ出し、 AutoHotkeyではレジストリを直接いじることも出来るので、 モード変更時に変えてやればよいだろうということで、

RegWrite, REG_DWORD, HKEY_CURRENT_USER\Control Panel\Desktop, CaretWidth, 0xa

みたいなものを変更時にやってやれば良いんじゃないか、と。

HKEY_CURRENT_USER\Control Panel\Desktopの下にあるCaretWidthというレジストリ値が、 デフォルトでは0 (0x1)になっていて、これを10 (0xa)に変更する設定です。

これをノーマルモードに入る時に実行して、インサートモードでは最後を0x1にしてあげれば できそう。

ということでやってみたのですが、実際レジストリの値は変更されるものの、 キャレットの太さは変わらず。

太くした状態で再ログインとかすると太く反映されますが、また再ログインするまで 変更は反映されません。

Windowsの設定のところでは即座に変わっていて、これも実際レジストリ値の変更を行っているので、 レジストリの値を反映した後に何らかそれを別の実際に使うところに反映するためのコマンドが必要な様です。

SystemParameterInfoA

直接レジストリの変更だけでは駄目だったようですが、 SystemParametersInfoA function というシステムワイドな設定変更をするものを見つけてくれた人がいました。

これを使った設定変更も作ってくれた人がいて、 これによってアプリ上でインサートモードからノーマルモードに移ると太いテキストカーソルに、 インサートモードに移ると細いカーソルに戻す設定を実現しました。

有効にする方法

vim_ahk v0.9.0以上のバージョンを入れると

Change to thick text caret when in normal mode

という設定項目がvim_ahkの設定の中に出てくるのでそれにチェックを入れます。

20210420_vimahksettings.jpg

もしくはvim_ahkを他のスクリプトの中から呼んでいるならvim_ahkを読み込む前に VimChangeCaretWidthの値を1に設定してください。

残っている問題

とりあえずそれっぽいものが出来たのですが、まだちょっと実用化が難しい状態です。

問題としては

  • 特定のアプリ上でしか変更が反映されない
    • 基本的にはWindowsネイティブなアプリのみが対象
    • Wordpad, Word, OneNoteなど
    • Evernoteなどに移ると常に元の太さのまま
  • 一部のアプリでは太くなった状態(ノーマルモード)で移るとキャレットは太い状態になっているが、インサートモードに移ってもカーソルが変わらない
    • Wordpadでノーマルモードに入り、そのままメモ帳に移るとキャレットが太い状態のまま維持される

Issues on VimChangeCaretWidth · Issue #65 · rcmdnk/vim_ahk

実際にやってみた様子:

20210420_vimahkcaret.gif

Wordpad上ではモードを切り替えるごとにキャレットの太さが変わっているのがわかります。

ただ、太いママメモ帳に移るとモードを変えても太いままになります。

一方で、Evernoteなどでは太い状態で移ってもEvernote上では元の細い状態が維持されます。

このあたり、レジストリの変更とは少し状態が違うようで、 まだうまく反映しきれてない部分があるみたいです。

メモ帳などの上で設定は維持されるものの変更するための命令が効かないのもよくわからない点です。

もし何かわかる方がいたら教えていただけるとありがたいです。

Sponsored Links
Sponsored Links

« Vieb: Electron製Vimライクな操作が出来るブラウザ vim_ahkで簡単にアプリケーション上で有効に出来るようにした »