Author Archives: AKIYAMA

2023-07-31

MS-Windows版 Emacs 29.1への移行作業

Emacs 29.1がリリースされたと聞いてファイル置き場を覗いてみたらまだWindows版が置いておらず、1日くらい待ってたまにはビルドしようかなーとソースコードを取りに行ったらすでにWindows版のバイナリが置いてありました。仕事が速いですね。

最近はIMEパッチも使っていないのでビルドする機会がほとんど無くなってしまいました。まぁ、自分でビルドしたら色々良いこともあるとは思いますが。細かい不具合を好きなだけ直せたりとかね!

それで一応移行作業をしたので以下その記録です。

(2025-02-24追記: Emacs 30.1の設定(MS-Windows)はこちら)

1.ダウンロード

https://ftp.gnu.org/gnu/emacs/

  • emacs-29.1.zip
  • emacs-29.1.tar.xz (展開してfind-function-C-source-directory変数に指定し、describe-functionからソースコードを追えるようにするため)

2.zipを展開して適当な場所に置く

3.起動してみる

パッと見問題無し。

4.補う必要のあるファイルを確認する

  • 相変わらずlibgccjit関連のファイルは含まれていないのでネイティブコンパイルはそのままでは出来ない。
  • gdk_pixbufのloadersもないので、SVG内のimage要素も表示されない。

5.MSYS2で必要なファイルを取り寄せる

あ、MSYS2はucrt64環境に移行してしまったのでmingw64環境のファイルは無いんだった。パッケージアーカイブから直接ダウンロードすることも出来るかもしれないけど、面倒なのでMSYS2環境からインストールしてしまう。

pacman -S mingw-w64-x86_64-libgccjit
pacman -S mingw-w64-x86_64-gdk-pixbuf2

6.SVG内の画像要素を表示できるようにする

まずは簡単な方から。 msys64/mingw64/lib/gdk-pixbuf-2.0 ディレクトリを emacs-29.1/lib/ へコピー。これでSVG内のimage要素は表示できた。 loaders.cache については何もしなくて大丈夫だった。画像形式によっては追加の依存ファイルがあるかも? とりあえずjpgとpngは問題なし。

(以前も書いたが、SVGの描画はlibrsvgが行っており、librsvgはlibgdk_pixbufのローダーライブラリを使用して画像を読み込むので、これらのファイルが無いとSVG内に画像が表示されない。Emacsがjpgやpngを描画する仕組みとSVG内にjpgやpngを描画する仕組みは全然別物なのだ。用途としてはel-easydrawの画像ツール)

7.ネイティブコンパイルできるようにする

次のファイルをコピー。

  • emacs-29.1/binへ
    • msys64/mingw64/binから
      • libgccjit-0.dll
      • libisl-23.dll
      • libmpc-3.dll
      • libmpfr-6.dll
  • emacs-29.1/lib/gccへ
    • msys64/mingw64/binから
      • as.exe
      • ld.exe
    • msys64/mingw64/libから
      • crtbegin.o
      • crtend.o
      • dllcrt2.o
      • libadvapi32.a
      • libgcc_s.a
      • libkernel32.a
      • libmingw32.a
      • libmingwex.a
      • libmoldname.a
      • libmsvcrt.a
      • libpthread.a
      • libshell32.a
      • libuser32.a
    • msys64/mingw64/lib/gcc/x86_64-w64-mingw32/13.1.0/から
      • libgcc.a

.aや.oは全部必要なのか、また、不足するものが無いのかは確認していない。

./emacs.d/early-init.el には次のように設定してあるが、あまり覚えていないので正しいかは知らない。

(when (and (fboundp #'native-comp-available-p) ;;emacs-28以降
           (native-comp-available-p) ;;libgccjitが使える
           (eq system-type 'windows-nt)) ;;Windowsの場合 (他必要に応じて条件を追加すること)

  ;; コンパイル用にemacsを起動する関数をラップし、
  ;; カレントディレクトリを一時的に変更する
  (defun my-comp-set-env-and-call (orig-fun &rest args)
    ;; 一時的にカレントディレクトリを emacs-28.1/bin にする
    ;; でないと emacs-28.1/lib/gcc/as.exe を見つけてくれない
    ;; また、emacs-async-comp-*.elというファイルをあちこちに生成してしまう。
    (let ((default-directory invocation-directory))
      ;; 元の関数を呼び出す
      (apply orig-fun args)))

  (advice-add #'comp-final :around #'my-comp-set-env-and-call)
  (advice-add #'comp-run-async-workers :around #'my-comp-set-env-and-call)

  ;; ライブラリの位置を指定する
  (setq native-comp-driver-options (list "-B" (expand-file-name (file-name-concat invocation-directory "../lib/gcc")) )))

8.org-datauri-image.elとorg-http-inline-image.elを無効化する

次のような警告が沢山出て何かと思ったら自分で書いたクソコードが火を噴いただけだった。

⛔ Warning (emacs): Redefining ‘file-exists-p’ might break native compilation of trampolines.
⛔ Warning (emacs): Redefining ‘expand-file-name’ might break native compilation of trampolines.

cl-letfで一時的にsymbol-function書き替えたから。

そのうち書き直したい。

2023-04-17

新しいマウスを購入(Logicool M750)

一昨日、昨日と新しいマウスを購入した。

これまで使っていたMX Anywhere 2の左ボタンが連打されるようになってしまったからだ。ウィンドウ移動時に最大化されてしまったりあちこちで誤操作して困っていた。ちょっと前にクッキークリッカーで高橋名人バリの連射をしたのが寿命を縮めたのだろうか?

順当に行けば代わりは後継機のMX Anywhere 3なのだろうけど、このマウスはちょっと高い(Amazonで11000円くらい)。それにこれまで2を使ってきて不満も無いわけでは無い。一番はバッテリー。バッテリーがすぐに切れてしまうのでしょっちゅう有線マウス状態で使っていた。ちなみに私は無線マウスにそれほど価値を感じていない。机の上で使っている分には線が付いていようがいまいが操作性に差は無いからだ。ただ、接続が楽なこととPCを引き出すときにケーブルが引っかからないのは良い所だろう。充電だけならテーブルの上に出してあるテーブルタップに繋げれば良いが、机の下のPCに繋げるとなると多少配線に苦労する。自宅のデスクトップ専用のマウスなのでマルチペアリングや軽量性は必要ない。あまりUSBポートにドングルばかり挿したくないのでBluetoothが良い。専用ドングルのみだと困る。左右チルトは使っていない。そう考えると何も後継機にこだわる必要は無いだろう。

そうしてWeb上で新しいマウスを探して目を付けたのがM650。安いマウスでも十分だとは思ったが変なものに当たって何度も買い直すようだと困る(結果的には買い直したがw)。信頼の置ける同じメーカーということでロジクールの中から一番無難そうなM650にした。近所の量販店に行ったついでに購入。意外なことに通販とほとんど変わらない値段だった。

ロジクール Signature M650MOW ワイヤレスマウス

単三乾電池一本で長期間動くのでバッテリー劣化で悩む心配は無い。握りやすさも問題ない。LサイズもあったがMサイズにした。手は大きい方だが、小さめなマウスを指先でちょこちょこ動かしたいので。そういう意味ではこれ以上大きいと困るギリギリのサイズ。モバイル用途ならもう少し小さいものを選びたいところ。ボタンは静音仕様だがクリック感に問題は無い。ホイールを回したときのクリック感も柔らかいがしっかりとある。接続性も問題なし。

しかし実際に使ってすぐに気がついたのが専用の中ボタンが無いということだ。私は中ボタンをよく使うのでMX Anywhere 2ではホイール下のジェスチャーボタンを中ボタンにして使っていた。しかしこのM650にはホイール下に独立したボタンが無い。もちろんホイールはクリックできて中ボタンとして機能する。しかし硬いので押しづらい。ホイールの回転は柔らかいので押そうとすると先にホイールが回ったりもする。長いことMX Anywhere 2を使っている間にこういう問題があったことをすっかり忘れてしまっていた。

el-easydrawにスクロール機能を付けたとき、私は中ボタンドラッグをスクロールに割り当てた。この手のソフトではよく見る操作体系だが私はあまり好きでは無くPhotoshopと同じSPACE+ドラッグが好きだったりする。しかしEmacsではSPACEをmodifierとして使う方法が無いので仕方なく中ドラッグにしたのだった(代わりにSPACEでスクロール・ズームモードになる機能も追加したがモード切替はやはり少々使いづらい)。試しにel-easydrawでスクロールしてみたが、やはりボタンが硬くてスクロールしづらい。ホイールも微妙に回ってしまうので何だか指先が気持ち悪い。

実はM650の上位機種であるM750にはホイールの下に中央ボタンがついているのだった。デフォルトでは速度切り替えボタンになっているが中ボタンに割り当てることも出来る。全体的な形はM650と同じで機能が増えてわずかに重くなっている程度だ。

Logicool Signature M750MOW ワイヤレスマウス

というわけで、かなり勿体ないような気もしたがM750を追加で購入した。中央ボタンの位置がMX Anywhere 2と比べてやや手前でわずかに押しづらくはあるが、まぁ、それほど大きな問題では無い。M650よりは大幅に楽に中ボタンが押せるようになった。ホイールのボタンの方はタブを閉じる操作に割り当てた。こりゃ便利だ。

ホイール(M650、M750で違いは無い)の回転は柔らかいクリック感がありMX Anywhere 2のようなフリースピン切り替えは無いが、フリーモードとクリックモードの中間といったところ。SmartWheelという機能でゆっくり回したときと高速に回したときに挙動が変わるが、かなり自然な動きになっている。ホイールをびゃーっとはじいたときはちゃんとそれらしい動きをする。中間くらいの動きで時々アレ?とわずかに違和感を覚えることもあるが、今のところ実用上特に問題は無い。

全体的にこれまでのMX Anywhere 2と比べて大きな問題は無く、コストパフォーマンスの高いマウスだと感じた。

2023-04-16 , ,

PowerShellからWindows Searchで検索する

el-winsearchからadoquery.exeを起動するのが嫌なのでPowerShellからWindows Searchを実行する方法を調べた。次のようにすれば良いらしい。

$conn = New-Object -ComObject ADODB.Connection
$conn.Open("Provider=Search.CollatorDSO;Extended Properties='Application=Windows';")
$query = "SELECT TOP 10 System.ItemUrl FROM SystemIndex WHERE System.Kind = 'picture'"
$rs = New-Object -ComObject ADODB.Recordset
$rs.Open($query, $conn)
While(-Not $rs.EOF){
  # 2023-04-18: 訂正
  Write-Output ($rs.Fields[0].Value -replace '^file:','');
  $rs.MoveNext()
}
$rs.Close()
$conn.Close()

System.ItemPathDisplayではなくSystem.ItemUrlを使うのは C:\ユーザー\ のようなローカライズされたパス名が出てきて都合が悪いから。しかしSystem.ItemUrlを使うと頭に file: が付いてしまうのでそれは出力前に削除している。

これをセミコロン区切りで1行にしてpowershellの-Commandオプションで実行することも出来る。スクリプトファイルにすると色々面倒なこともあるので。-Commandオプションで実行する場合は実行ポリシーなどは関係ないのだろうか。よく知らない。とりあえず手元では動いている。

というわけでel-winsearchはもはや専用のexeを必要としなくなった。 file: の部分も無くなったのでconsult-winsearchから使ったときにEmbarkやMarginaliaも正しく動くようになった。

consult-winsearchを使ったときにVerticoでtruncate-linesがtにならない問題に遭遇したが、検索オプションの書き方をpromptに無理矢理載せたことと、vertico–resize-windowが改行のあるpromptを考慮していないのが原因のようだ。次のように修正した。

;; truncate-linesにする条件が不完全なのを直す。
(with-eval-after-load 'vertico
  (cl-defgeneric vertico--resize-window (height)
    "Resize active minibuffer window to HEIGHT."
    (setq-local truncate-lines (<
                                ;; 旧:(point)
                                ;; ↑ここを修正した。
                                ;; 横に長いpromptで切り詰め表示すると入力がウィンドウ幅を超えたときに検索結果も水平スクロールされてしまうのを防止しているのだと思う。
                                ;; しかし(point)では改行や全角を考慮していない。
                                ;; 新:
                                (string-width
                                 (buffer-substring
                                  (let ((inhibit-field-text-motion t))
                                    (line-beginning-position))
                                  (point)))
                                ;;以下元のまま
                                (* 0.8 (vertico--window-width)))
                resize-mini-windows 'grow-only
                max-mini-window-height 1.0)
    (unless (frame-root-window-p (active-minibuffer-window))
      (unless vertico-resize
        (setq height (max height vertico-count)))
      (let* ((window-resize-pixelwise t)
             (dp (- (max (cdr (window-text-pixel-size))
                         (* (default-line-height) (1+ height)))
                    (window-pixel-height))))
        (when (or (and (> dp 0) (/= height 0))
                  (and (< dp 0) (eq vertico-resize t)))
          (window-resize nil dp nil nil 'pixelwise))))))