最近のEmacs設定

あれ?もう三月?という程度には時間の流れが早くて色々ビビってます。 最近仕事の方に時間が割かれがちなので、ちょっと埋め草的にEmacsの設定を紹介してみます。 ...

March 1, 2022 · derui

最近のEmacs設定

あれ?もう三月?という程度には時間の流れが早くて色々ビビってます。 最近仕事の方に時間が割かれがちなので、ちょっと埋め草的にEmacsの設定を紹介してみます。 ...

March 1, 2022 · derui

Emacs 29以降のmode lineが気にいらない場合

今年も終わりですね。なんだかんだ色々ありましたが、個人的には総じて悪くない年だったんだじゃないかと思ってます。 多分今年最後の記事ですが、ネタが無いので小ネタでお茶を濁そうかと・・・。 <!–more–> Emacs29での結構重要な変更 私は現在、 native comp + pgtkを利用したい、という理由でEmacsのmasterを適宜ビルドして利用しているのですが、29の開発フェーズに入ってからビルドしなおしたら、なんか画面に違和感を覚えました。 さて、左側がアクティブなバッファ、右側が非アクティブなバッファです。何が違うでしょうか?まぁ見たまんまですが、mode lineのフォントが明らかに異なります。 私は現在フォントとしてはHackGenを愛用しているので、等幅フォントとなっています これは、Emacs 29において、mode lineをプロポーショナルフォントを利用する、という決定が入ったためらしいです。 https://lars.ingebrigtsen.no/2021/11/24/the-most-controversial-change-in-emacs-history/ ↑の記事によると、かつてあったXEmacsでmode lineにプロポーショナルフォントを導入していたらしく(私もその時代はLinuxメインではない)、それがGNU Emacsにも導入されたことによる、ということのようです。 しかし私は等幅でありたい そもそもプロポーショナルフォントを用意していないので、見た目もよくないしガタガタするし、なので、この設定をさくっと無効化します。 Emacs 29から、mode lineのfaceとして、 mode-line-active というものが追加されています。これが、アクティブな場合のmode lineに対する設定となっています。 これのフォント設定がプロポーショナルなものを利用する、ということになっているので、要はこいつを元々のものに戻してやればいいです。 (leaf *mode-line-face :if (version<= "29" emacs-version) :config ;; mode lineをvariable pitchではなく等幅フォントを利用する。 (set-face-attribute 'mode-line-active nil :inherit 'mode-line)) プロポーショナルじゃなくてvariable pitchとなっていますが、まぁ実用上はどっちでも一緒です、きっと。 私はleafを利用している & Emacs 28とかでも利用するケースがあるので、バージョン指定を入れてますが、masterしか使わん!という人はバージョン指定を抜いてもよいかと。 masterならではの問題 とりあえずは対処できましたが、こういった(影響のある人にとっては)ドラスティックな変更が入ってくるのも、masterを利用する醍醐味?かな、と思う一時でした。調査と修正自体は10分ちょっとでできたんですが、最初は違和感がある・・・けどなんだ?という感じでしたので。 こういうのがあるとmasterは・・・ってありがちですが、でもnative comp + pgtkはとても快適なので、Wayland環境で生活されている人は是非一度試してみることをお勧めします。 fcitxとかでの入力がうまくできない?らしいので、SKKなりmozcを利用する必要がありますが。 それではよい年末年始をお過ごしください。

December 26, 2021 · derui

completion-category-overridesで使う値を取得する

今回は超小ネタです。 <!–more–> 最近はEmacs上でのcompletionとして、orderlessなどの標準のcompletion-readなどに則ったものを利用してます。Emacsの標準補完は、実はかなり柔軟性に富んでいて、様々なカスタマイズが可能になっています。 completion-readのカスタマイズでは、 completion-category-overrides という変数で、completion-readによるマッチング方法を categoryごとに 変更することができます。 このcategory、 completion-metadata という関数で取得できるmetadataから取得することができます。 (completion-metadata-get (completion-metadata "" table nil) 'category) このtableとは、(私の理解だと)completion-readの第二引数として渡す関数です。この関数は、第3引数としてactionを取り、このactionに 'metadata というシンボルが渡された場合は、metadataを返す必要があります。 completion-metadata-getはこれらのmetadataから、特定の情報を取得するものです。なので、あるパッケージの補完をカスタマイズしたいときは、これを調べればカスタマイズできます。 ・・・が、場合によってはcompletion-readの呼び出しでlambdaを利用していて、 completion-metadata が使えないケースがあります。 実際、org-roam-node-findではlambdaで渡されており、categoryを知るためには結局その中身まで見る必要がありました そういう場合は、しかたがないのでパッケージの中を completion-read で検索してみると大体見付かります。 そんな場合もあるんだよ、というメモでした。

September 4, 2021 · derui

Emacsでの補完とかを脱ivy/selectrumした

久々(約4年振り)に眼鏡を新調しました。といっても注文して決済しただけで、まだ受け取っていないのですが。 さて、今回はEmacsの補完をivyから完全に切り替えたのでその話を書こうと思います。とはいえかなりライトなお話ですが。 <!–more–> 補完インターフェースの遍歴 なんだかんだ、Emacs(Meadow含め)を使いつづけて早1x年が経過してますが、その間に補完インターフェースはその時々のトレンドに乗ってきました。 Anything Helm Ivy Ivy + posframeもやったりしました selectrum どちらかというと個人的にはこだわりはないので、そのときどきで一番勢いがあるものに乗っかることで楽をしている感じですね。 今回の変更先 ついこの間まではivyからselectrum + consultとなっていましたが、以下の記事を見て、ご他聞に漏れずverticoに変更することにしました。仕事でもそうですが、標準に乗っかるって大事ですね。 https://blog.tomoya.dev/posts/a-new-wave-has-arrived-at-emacs/ selectrumからverticoへの変更 さて、実際に乗り換えたのはインターフェースだけなので、selectrumからverticoへの移行のみが焦点となりました。 ・・・が、そもそもほとんどカスタマイズが不要な状態で(唯一やっていたのはmini-frameくらい)利用していたので、正直ほとんど変更することもなかったです 実際に設定中でもたったこんだけです。 (leaf vertico :straight t :custom ;; 最大20件まで表示するように (vertico-count . 20) :config (vertico-mode)) 個人的には、Interfaceとかはあんまりいじりすぎないようにしています。よほど色がどぎついとかそういうのは弄りますけど。 mini-frameを利用しないようにした理由 さて、selectrumを利用していたとき、ivy-posframeを利用していたのと同じ感じで利用できれば、ということでemacs-mini-frameを利用していました。 しかし、これはこれで結構難点がありました。 現在の視点に関わらず、常に一定の場所に表示される ivy-posframeとかだと、カーソルのそばとかに表示できたりします 配色の問題だが、borderlessなので一瞬境目を見失う といったものが日々利用する上でだんだんストレスになっていました。固定位置なのであれば、正直minibufferを見るのと変わらんやん・・・ということもあり、verticoへの移行を期に削除しています。 migemoるようにした 今回、orderlessとverticoを導入したことで、emacsの補完システム(実はかなり充実している)を利用する形で、結構お手軽に変更できるようになっています。 https://nyoho.jp/diary/?date=20210615 こちらの記事を参考、というかほぼ丸パクリさせていただいて(多少アレンジはしてます)、無事consultでもmigemoることに成功しました。最近はorg-roamでメモを取るようにしているので、ファイル名とかを日本語検索するのが億劫になっていたところだったので・・・。ちなみにmigemoは自作のmigemocamlを利用しています。 そういえば、単独でdictを生成できるようにしたのに、まったく記事を書いていないので、これについては後程記事にしようと思います。 軽快・快適な補完生活を 現在、Emacsのpgtkブランチを利用することで、 Wayland native + native compileな環境を利用できるようになり、かなりEmacs上が快適になっています。これだけ快適になると、さらにVSCodeとかに移行するモチベーションが無くなるのが困ったところですね。 とはいえ、快適な補完は現代的な生活における必需品だと思います。Spacemacsとかではなく、vanillaのEmacsを利用している方は、是非これらのパッケージを利用してみることをお勧めします。快適ですよ。

June 19, 2021 · derui

Emacsのinit.elをorgで書く方法と、変更時に楽をしてみる

ふと気づいたら、転職して一年経過していました。一年のほとんどがコロナ影響下にあったのは、まーいい経験になったなーと。 さて、最近Emacsのinit.elをorgで書くようにしてみたのと、ちょっとした工夫をしてみたので、それについて書いてみます。 <!–more–> なぜinit.elをorgファイルにするのか やってみたかったから 身も蓋もない理由ですが、とりあえずは上の理由が一番に挙げられます。しかし、ちゃんとした利点もあります。 org-modeの強力な編集機能を使える コードブロックの周辺にコメントとして残すよりも表現力が高いですし、リンクとかもさっくり貼れます 折り畳みが自然にできる org-modeなので 部分での管理が楽 まぁいくつか理由はありますが、orgファイルにすることで、多少でも見通しがよくなるので。 init.elをinit.orgに変更する方法 org-modeには、babelという、色々な言語のコードブロックを、org-modeの中で実行するための枠組みを提供するlispが含まれています。 こいつを使うと、org-modeに書いたemacs lispを簡単にinit.elにすることができます。というかorg-mode公式で紹介していたりします。 私のデフォルトのinit.elは、今これしか書いてません。 https://github.com/derui/dot.emacs.d/blob/master/init.el (require 'org) ;; Do always overwrite init.el from generated source from init.org (org-babel-tangle-file (expand-file-name "init.org" user-emacs-directory) (expand-file-name "init.el" user-emacs-directory)) (load (expand-file-name "init.el" user-emacs-directory)) (message "Once kill emacs for apply new init.el written from init.org") (kill-emacs) org-babel-tangle-file という関数で、orgファイルにあるコードブロックを、指定したファイルに書き出すことができます。対象のorgファイルにemacs lispしか書いていなければ、吐き出されるのもemacs lispになります。 まー、私が書くよりも、すでに色んなところでこれよりも細かく記述されているので、参考サイトに挙げたサイトを見てみることをオススメします。 orgからinit.elを生成した場合の注意点 さて、これで起動するとinit.orgからinit.elが生成できるわけですが、最初に生成した場合、色々と問題が発生するケースがあります。 straight.elとかで最新のorgを入れていたりする場合、大抵上手く動きません 上が影響して、他のパッケージも上手く動かない場合があります そのため、私のinit.elでは、起動して読み込み終わった直後に死ぬようにしてあります。初回だけすぐ終了してしまいますが、どうせ一回終了しないと正しく起動しないので・・・。 init.elの初期化めんどくさい問題 一度生成されたinit.elは、当然ながらinit.orgを読み込むようには(大抵)なっていません。そうなると、init.orgの内容をちゃんと反映させる場合、以下のような手順を踏む必要があります。 init.orgを編集する init.elの内容を元にもどす git checkout などで Emacsを再起動するか、init.elを読み込む 特に2がめんどくさいです。ぶっちゃけ、init.orgを更新したらinit.elを初期化しておいてもらいたいです。 ということで、以下のような設定を追加しています。(実際は、 after-save-hook ではなく、自作関数を登録する専用のhookを用意しています) ...

March 13, 2021 · derui

Emacsのinit.elをorgで書く方法と、変更時に楽をしてみる

ふと気づいたら、転職して一年経過していました。一年のほとんどがコロナ影響下にあったのは、まーいい経験になったなーと。 さて、最近Emacsのinit.elをorgで書くようにしてみたのと、ちょっとした工夫をしてみたので、それについて書いてみます。 <!–more–> なぜinit.elをorgファイルにするのか やってみたかったから 身も蓋もない理由ですが、とりあえずは上の理由が一番に挙げられます。しかし、ちゃんとした利点もあります。 org-modeの強力な編集機能を使える コードブロックの周辺にコメントとして残すよりも表現力が高いですし、リンクとかもさっくり貼れます 折り畳みが自然にできる org-modeなので 部分での管理が楽 まぁいくつか理由はありますが、orgファイルにすることで、多少でも見通しがよくなるので。 init.elをinit.orgに変更する方法 org-modeには、babelという、色々な言語のコードブロックを、org-modeの中で実行するための枠組みを提供するlispが含まれています。 こいつを使うと、org-modeに書いたemacs lispを簡単にinit.elにすることができます。というかorg-mode公式で紹介していたりします。 私のデフォルトのinit.elは、今これしか書いてません。 https://github.com/derui/dot.emacs.d/blob/master/init.el (require 'org) ;; Do always overwrite init.el from generated source from init.org (org-babel-tangle-file (expand-file-name "init.org" user-emacs-directory) (expand-file-name "init.el" user-emacs-directory)) (load (expand-file-name "init.el" user-emacs-directory)) (message "Once kill emacs for apply new init.el written from init.org") (kill-emacs) org-babel-tangle-file という関数で、orgファイルにあるコードブロックを、指定したファイルに書き出すことができます。対象のorgファイルにemacs lispしか書いていなければ、吐き出されるのもemacs lispになります。 まー、私が書くよりも、すでに色んなところでこれよりも細かく記述されているので、参考サイトに挙げたサイトを見てみることをオススメします。 orgからinit.elを生成した場合の注意点 さて、これで起動するとinit.orgからinit.elが生成できるわけですが、最初に生成した場合、色々と問題が発生するケースがあります。 straight.elとかで最新のorgを入れていたりする場合、大抵上手く動きません 上が影響して、他のパッケージも上手く動かない場合があります そのため、私のinit.elでは、起動して読み込み終わった直後に死ぬようにしてあります。初回だけすぐ終了してしまいますが、どうせ一回終了しないと正しく起動しないので・・・。 init.elの初期化めんどくさい問題 一度生成されたinit.elは、当然ながらinit.orgを読み込むようには(大抵)なっていません。そうなると、init.orgの内容をちゃんと反映させる場合、以下のような手順を踏む必要があります。 init.orgを編集する init.elの内容を元にもどす git checkout などで Emacsを再起動するか、init.elを読み込む 特に2がめんどくさいです。ぶっちゃけ、init.orgを更新したらinit.elを初期化しておいてもらいたいです。 ということで、以下のような設定を追加しています。(実際は、 after-save-hook ではなく、自作関数を登録する専用のhookを用意しています) ...

March 13, 2021 · derui

Windows10 + WSL2で環境を整えた

帰省のイベントである、自分のノートPC(Windows10)に開発環境を整備する時期になったので、今回はVagrantからWSL2を使ったものにしてみました。 見切り発車ですので出来るかどうかは不定です。ではいってみましょう。 <!–more–> 不安な点 いつもはVagrant上に構築したX11環境で開発していたわけですが、今回はWSL2になるということで、いろいろ考える必要がありそうでした。 WSL2ではUbuntu20.04/Debian/SUSEくらいしか使えない いつもはArchLinuxを使っているので、色々と不安な点が・・・ Xserverが必要 Windows上のX serverを入れる必要があります 自分のdotfileが使えるのか・・・? Gentoo/Archlinux用になっているようなものなので、色々厳しそう? 今回の要件 以下を目標にします。努力目標は OPT がついてます。 EmacsをGUIで使える 自分のdotfile/.emacs.dを使えている OCaml/opam/Node.jsが入っている (OPT) Emacsからmozc_emacs_helperを通してWindows上のGoogle日本語入力を使えている (OPT) EmacsからWindowsの方のブラウザとかを使える Emacsとterminalだけで大体生きてるOld typeなので、これくらい出来ればだいたい何とかなります。 WSL2のインストール いつものごとく画像はありませんがご容赦を。以下の手順でWSLを有効にします。なお、前提としてWindowsのOS versionがMay Update以降である必要があります。お気をつけて。 アップデートが必要なことを忘れていてだいぶ時間を食ったのは内緒です インストールと更新方法は、Microsoftの公式ドキュメントが詳しいのでそっちを見ましょう。 https://docs.microsoft.com/ja-jp/windows/wsl/install-win10 一応手順を書いておきます。 PowerShellを管理者権限で開く dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart 再起動する またPowerShellを管理者権限で開く wsl --set-default-version 2 なんかURLが表示されるので、アクセスしてWSLのkernel updateを入手してインストールする Windows StoreからWSLのディストリビューションをダウンロードする(今回はUbuntu 20.04を選択) Windows Storeからダウンロードしたディストリビューションを起動する しばらく待つ(数分程度) UNIX username/passwordを入れる。Windows usernameと同じにしとくのが無難な模様 これでいけるはずです。WSLにアクセスする時は、Windows TerminalとかcmdとかPowerShellとかお好きなもので wsl と打てば、デフォルトで設定されているディストリビューションに対してアクセスできます。 WSLにいろいろインストール WSL2は普通のLinuxなので、色々設定をしていきます。ただ、WSL2は若干特殊な環境なので、systemctlは使えないものと考えるのが良さそうです。 timezoneはだいたい初期状態で問題なさそうでした。 ...

August 8, 2020 · derui

Emacsの設定管理をuse-packageからleaf.elにしてみた

大分長い間use-packageを利用していましたが、一日掛けてleaf.elに移行してみました。leaf.elの利点や移行時の注意などをまとめたいと思います。 <!–more–> use-packageに感じていた問題点 ・・・というのは実はあまりないんですが、あえて言えば次のような点でした。 設定のgroupingがしづらい use-packageはネストすることを前提としていない?ので、packageの設定が分散しがち bindの設定方法が独特 aggressive-indentを使っていると、中々にindentが荒ぶります 標準パッケージをきちんと利用する方法がよくわからない あまり頻繁に.emacs.dを更新していない、というのもあるんですが、端的に言うと まーいいか という状態でした。 leaf.el leaf.elは、 leaf.el is yet another use-package. として作成されたpackageです。use-packageと比較してどうか?というのは、作者が書いている記事を見たほうが早いでしょう。 https://qiita.com/conao3/items/dc88bdadb0523ef95878 利用してみた感じでいうと、大体use-packageと同じ使用感ですが、色々と統一感が出るのがいい感じです。また、設定をグルーピングするという目的でも使えるので、use-packageで不自由だった部分が解消されて設定がスッキリしました。 移行後の内容は、以下のrepositoryを見てもらったほうが早いです。 https://github.com/derui/dot.emacs.d/blob/master/conf/package-config.el まだ修正中なので、いくつか不具合を抱えています。また、packageがあまりかかわらず、設定のフォルダとして利用した例は次のファイルに書いています。 https://github.com/derui/dot.emacs.d/blob/master/conf/emacs-base-setting.el leaf.elに移行してみて ただ、leaf.elもいいところばかりではなく、いくつか設定上の問題がありました。 bindingが上手く行かない問題 leaf.elでは、bindingに設定した関数は、基本的にそのpackage内の関数である、とみなそうとします。 (pp (macroexpand '(leaf evil :bind (:evil-normal-state-map ("f" . evil-forward-quote-char) ("F" . my:evil-forward)) :config (defun my:evil-forward () ())))) ;; => ;; (prog1 'evil ;; (leaf-handler-leaf-protect evil ;; (unless ;; (fboundp 'evil-forward-quote-char) ;; (autoload #'evil-forward-quote-char "evil" nil t)) ;; (unless ;; (fboundp 'my:evil-forward) ;; (autoload #'my:evil-forward "evil" nil t)) ;; (declare-function evil-forward-quote-char "evil") ;; (declare-function my:evil-forward "evil") ;; (defvar evil-normal-state-map) ;; (leaf-keys ;; ((:evil-normal-state-map :package evil ;; ("f" . evil-forward-quote-char) ;; ("F" . my:evil-forward)))) ;; (eval-after-load 'evil ;; '(progn ;; (defun my:evil-forward nil nil))))) こんな感じに。このとき、特に問題になるのが 自作関数 です。autoloadしようにも、そのpackage内に存在していないので、当然ながらload出来ません。また、こういう関数は、大抵このpackageの関数を使っているので、 :config 内に書いたりしています。そうなると、bindしようにも :config が実行されるのは、上の例でいくとevilがloadされた後になるんですが、その辺りが上手く動かない、というケースが多発しました。 ...

November 17, 2019 · derui

Excelのページ指定印刷をPowerShellでやる方法

最近人事/総務からのヒアリングした業務上の問題を解決していく、という社内プロジェクトに参加しています。 その中で、割と調べても出てこなかった事柄をメモしておきます。 <!–more–> 要望 今回解決したいのは、次のような問題でした。 色々な事情で、Excelから紙で印刷いないといけない 親会社の意向とかいろいろあるようで Excelの数が多い だいたい社員数くらいある(現状だと300↑) 印刷するのが手作業で辛い しかもそういう業務がけっこうある とにかく問題としては、 Excelを開く→最初のページだけ印刷する という業務が多く、かつ時間がかかる、と。電子承認とかそういう方向に行きたいらしいですが、まーいろいろ事情があるようで。 方針の検討 とりあえず抜本的ではないが、ある程度作る労力と、結果の省力化に貢献できるものとして、次のようなツールを作ることにしました。 Excelマクロの実行が必須 実行しないと正しい状態にならないので・・・ Excelの 1ページ目だけ 印刷できる フォルダ内のExcelを一気に印刷できる 任意のフォルダでやりたい 困ったこと 人事/総務の方々は、ITレベルが様々なので、Windows標準で入っているものを使う、ということで、 PowerShell を使うことにしました。 ところが、いろいろ調べて(ググって)みても、 ExcelからBookを印刷する というものはあっても、 指定したページだけ印刷する ということをやっている人がまずいないっぽいという・・・。 フォルダ内のExcelを印刷するという回答 色々試す 色々試した所、次のサイトが気づきになりました。 https://docs.microsoft.com/ja-jp/office/vba/api/excel.workbook.printout このページ、Office VBAのヘルプですが、ここに引数が書いてあります。 名前 必須 / オプション データ型 説明 From 省略可能 Variant 印刷を開始するページの番号を指定します。 この引数を省略すると、最初のページから印刷します。 To 省略可能 Variant 印刷を終了するページの番号を指定します。 この引数を省略すると、最後のページまで印刷します。 Copies 省略可能 Variant 印刷部数を指定します。 この引数を省略すると、印刷部数は 1 部になります。 Preview 省略可能 Variant True の場合、印刷をする前に印刷プレビューを実行します。 False、または省略した場合、直ちに印刷を行います。 ActivePrinter 省略可能 Variant アクティブなプリンターの名前を指定します。 PrintToFile 省略可能 Variant True の場合、ファイルへ出力します。 引数 PrToFileName が省略された場合、出力先のファイル名を指定するためのダイアログ ボックスを表示します。 Collate 省略可能 Variant True の場合、部単位で印刷します。 PrToFileName 省略可能 Variant _PrintToFile_がTrueに設定されている場合、この引数は印刷先のファイル名を指定します。 IgnorePrintAreas 省略可能 Variant True の場合、印刷範囲を無視してオブジェクト全体を印刷します。 これをPrintOutに指定すればいいんじゃね!?ということで、こんな感じにしてみました。 ...

July 10, 2019 · derui