vim-jp / issues

有志で既知のバグや要望を検討・管理し、オフィシャルへの還元をしていきます。
https://vim-jp.org/
341 stars 11 forks source link

CUI 版 Vim でウィンドウのピクセルサイズを取得したい #1440

Closed mikoto2000 closed 2 weeks ago

mikoto2000 commented 3 weeks ago

内容

1438 の続きのようなものです。

やりたいこと

CUI 版 Vim でウィンドウのピクセルサイズを取得したい

モチベーション

echoraw で Sixel 出力が可能となったため、画像表示プラグインなどの可能性が見えてきた。 その際に、ウィンドウのピクセルサイズまでわかると画像をウィンドウにフィットさせたりなど、機能の可能性が広がる。

Pros 良くなる点

正確なピクセルサイズが取得できることにより、画像出力プラグインなどの可能性が広がる。

Cons 悪くなる点

行列レベルで十分なケースでも、ピクセルレベルの値を取得するための処理の時間が加算される。

実現方法

親プロセスの tty に対して TIOCSWINSZ を発行し、サイズを取得、そこからフォントサイズを計算。 計算したフォントサイズを基にピクセルレベルのサイズを求めるようにする。 GUI に関しては、既存実装と同様の挙動を保つようにする。

試作を https://github.com/vim/vim/compare/master...mikoto2000:vim:improve-tiocswinsz-pixel-size に作成した。

Vimのバージョン

9.1.821

OSの種類/ディストリ/バージョン

その他

また、「そもそもこういう要望は Vim に取り込まれないよ」など、アドバイスがありましたらお教えいただけると幸いです。

h-east commented 3 weeks ago

CUIの場合は端末に問い合わせる方式が良い気がしますね。

  1. termcapオプション 't_~' (デフォルト値: ^[[14t ?)と定義済変数 v:term~resp を追加する。
  2. (Vimが)端末に問い合わせて、応答があれば v:term~resp にセット(値は ^[[4;高さ;幅t ?)して、自動コマンドイベント TermResponseAll をトリガー。
  3. (ユーザーが)ピクセルサイズを参照したいタイミングで v:term~resp をパースして、高さと幅をゲット。 (もしくは、あらかじめ自動コマンドイベント TermResponseAll 処理内でパースして変数にセットしておく)

参考help :h t_RF :h termresponse-variable :h v:termrfgresp

PS Vimの:term内のVimの場合の端末の処理は、Vimのlibvterm実装に追加してあげないといけない。

mikoto2000 commented 3 weeks ago

@h-east コメントありがとうございます。 Vim 内で以下コメント相当のことを行い、 v: 変数に格納しておくと理解しました。 https://github.com/vim-jp/issues/issues/1438#issuecomment-2449915715

ターミナルの知識不足でまだ実装イメージが湧いていませんが、各用語について調べつつ実装できないか試してみます。

mikoto2000 commented 3 weeks ago

ひとまず現在 ioctl を使用している箇所をエスケープシーケンスを使用するように修正した。

https://github.com/vim/vim/compare/master...mikoto2000:vim:improve-tiocswinsz-pixel-size

termcap, v:termresponse がわからないので引き続き調べていく。

mikoto2000 commented 3 weeks ago

いったん「:term 上で動くアプリがサイズを取得する」というのは忘れる。 「Vim script にウィンドウのピクセルサイズを渡したい」という目的に絞れば、現状の実装方針で大体良いはず。(termcap や v:termresponse を意識しなくてもよいはず) という認識になりました。

mikoto2000 commented 3 weeks ago

方針は以下。

mikoto2000 commented 3 weeks ago

いや、先に TIOCSWINSZ の修正で「正しいピクセルを返す」の PR を出してから、「これ使えば getwininfo() にピクセルサイズ載せるのもできるのでは?」で PR 出す方がいいか?

mikoto2000 commented 3 weeks ago

少し寝かせてから見直して PR 出してみる。

title: Added pixel size in getwinsize().

What I want to do? I want to get the pixel size of the window in the CUI version of Vim.

Motivation: The ability to output Sixel in echoraw has opened up possibilities such as image display plugins If the pixel size of the window can be known, the possibilities for functions such as fitting the image to the window will be expanded.

Pros: The ability to obtain precise pixel size opens up possibilities for image output plugins.

Cons: Even in cases where the matrix level is sufficient, processing time to obtain pixel level values is added.

Implementation:

mikoto2000 commented 3 weeks ago

コーディングスタイルの再チェックと Windows でのビルド確認が済んだらプルリクエストを出してみます。

h-east commented 3 weeks ago

@mikoto2000 typo. s/echora/echoraw/

mikoto2000 commented 3 weeks ago

@h-east おっと気づきませんでした、ありがとうございます!

mikoto2000 commented 3 weeks ago

修正後のソースでテストが止まるので足踏みです。 Enter を押さないと進まないテストがある...?

mikoto2000 commented 3 weeks ago

あ、ブランチ名を変更して rebase しました。 https://github.com/mikoto2000/vim/commit/0efaeadbcc7a90e4b5debba938a6c54cabffebda

mikoto2000 commented 3 weeks ago

エスケープシーケンスで値をやり取りする間は、端末を非カノニカルモードにしてエコーも無効にする必要がある?

mikoto2000 commented 3 weeks ago

:call getwininfo()<Enter> したあと、もう一度 <Enter> を押下しないと結果が表示されない。出力が <Enter> までバッファされている?

mikoto2000 commented 2 weeks ago

改善方法がわからないので、 TIOCSWINSZ を使う方法に戻してテストを流してみる。

mikoto2000 commented 2 weeks ago

TIOCSWINSZ を使う方法に戻してテストしたら流れ切った。こっちバージョンで出してみる。

mikoto2000 commented 2 weeks ago

以下でマージされました。ご助言、コメントありがとうございました! https://github.com/vim/vim/commit/1083cae7091f006249c1349d0575412d2ff6a7dc