qmk_firmwareの日本語配列からかな入力をする

すっかり在宅に慣れてきましたが、ちょっと出かけることも出来ないというのが割とストレスですね・・・。 最近は出勤時間分の時間が空いたので、環境の改善をよく行っています。そんな中で、日本語入力も改善したので、それについて書こうかと思います。 <!–more–> qmk_firmwareと日本語入力 いくつかqmk_firmwareでカナ入力の方式を実装してきましたが、今までの実装だと、以下のような問題がありました。 どうしてもローマ字で入力させる必要があったため、マッピングが肥大する 肥大すると、当然ながら他の機能を追加できないため、使い勝手が悪い 濁音を後置する場合、どうしても不自然になる 本来であればIME側でやってくれることを、ファームウェア側でやる必要がある 遅延で入力させることもできるが、いかんせん表示がかなり不自然になる 特にnew stickney配列を使うようになって顕著なのが、濁音後置になったため、濁音の入力時に考えなければならないことが増えました。 timerを使った遅延入力にすると、出力自体が遅延するため、今入力している内容を把握するのが大変です。濁音キーを入れた時に、一回入れた文字を消して新しい文字を入れる、ということもしてみたりしましたが、これはこれで誤動作が多く、今ではお蔵入りになっています。 なぜIMEのかな入力を使わないのかと IMEでローマ字ではないかな入力を使えば、こういう問題はある程度解決されます。今までやってなかったのは、ひとえに マッピングがめんどくさい という点が大きかったです。 また、ローマ字では、キーボードのレイアウトがUSでもJPでも全く問題なく扱うことが出来ますが、かな入力では、USではそもそも入力できないキーコードが必要になります。こういった点を解決できるのかが把握できなかったため、放置していましたが、一念発起して対応してみました。 対応した結果 こんな感じになりました。key sequenceが1文字になったことと、濁音と半濁音のハンドリングを自分で行う必要が無くなったため、全体の容量は減っています。 https://github.com/derui/qmk_firmware/tree/master/keyboards/crkbd/keymaps/derui ただ、小書き文字に対する対応が必要であるため、母音を入力するときだけは遅延が発生する状態です。慣れればdelayを低くしてもいいとは思いますが、今のところは置いておいてます。この小書き文字の部分をスマートに実装できれば、かなりの使い勝手になりそうだと勝手に思ってます。 また、Emacsでの設定も追加しました。 (setq mozc-keymap-kana mozc-keymap-kana-101us) この対応をした結果、以下のようになりました。 Fcitx + mozcでは特に問題なく使える Emacs + mozcでは、 ろ と ー に対応するkey codeをハンドリング出来ていないため、本来の入力と異なるmappingが行われてしまっている この2つ以外は、問題なくnew stickney配列を再現できている Emacsでもfcitxを使って、mozc.elを使わない、とかすればいいかもしれないが・・・ mozc-keymap-kana-106jp というkeymapに変更すると、異なる文字が入れられるようになってしまう 多分USレイアウトとJPレイアウトで記号が異なる部分で違っている USレイアウトにないkey codeをハンドリングすることが出来ればなんとかなるので、mozc.elの中を覗いているところ 仕事で使うMacでは試していない ローマ字でいいじゃん、という誘惑との戦い 正直、これだけやっていても、仕事で急いでいるときにはローマ字で入力してしまっているという体たらくなので、ローマ字でいいんじゃないか?と思うときがないわけではありません。 特に、価値のあること(大抵金銭的なもの)以外に時間を使うことに対して否定的な環境にいると、非効率自体が無駄とみなされがちです。 しかし、異なる入力方法に親しむということは、異なる能力開発をしている、ということでもあります。この入力を自然に行うためにはどうするべきか?という問いに答えるのは自分しかいません。問題解決能力を鍛えるということは、みんな大好き人生100年時代にもマッチするのではないでしょうか。 なんだかんだ書いてみましたが、つまるところ自分の趣味なので、まー好きにさせてくれよ、というところでしょうか。 かな入力はIMEに任せよう 濁音後置型のかな入力は、IMEのJISかなに任せると楽が出来ます。新下駄配列とかの濁音も一モーションで入力するような配列では工夫する必要がありそうですが、送信するキーシーケンスの数は減るはずです。 qmk_firmwareでカナ入力を実装している方の参考になれば幸いです。

April 29, 2020 · derui

Enzymeの代わりにtesting-libraryを使うようにしてみた

いろいろコロナの影響が出てきましたが、いかがお過ごしでしょうか。会社でも東京勤務は基本的に在宅となりました。 今まで、ReactとかのIntegration testにはenzymeを使っていましたが、Preactに切り替えた際に課題が多発したため、なんとかして解決してみました。 <!–more–> Preact + Enzymeの課題 Enzymeは元々jsdomとセットで利用していたのですが、 React -> Preact に切り替えたとき、仕様の違いによってテストが動かなかったです。 主な違いとしては、 Preactではshallow renderingが出来ない Portalで色々問題がある これはReactでも色々あるみたいなので、Preactに限ったことではないですが React/Preactでeventの扱いが全く異なる といったあたりです。特に既存のtestでshallow renderingを多用しており、大抵は動くのですが、 React.createPortal を使っているところが全滅でした。 testing-library React.createPortal および Preactの createPortal ですが、いずれも libraryの管理範囲外のDOMにrenderingする というcomponentを構成します。 React.jsの場合、EnzymeのAdapter側でかなり色々やって対応しているようですが、Preactの場合、 Componentを完全にrenderingする というそもそもの仕様から、対応が無理っぽいです。ちゃんと見ていませんが、third partyがlibraryの内部実装に依存している、というのはあまりよろしくないように感じます。 また、よく考えると、jsdomとはいえ実DOMにrenderingするということは、もう それはIntegration Testじゃないのか? という意見を見て、 ( ゚д゚)ハッ! となりました。そんな折に見つけたのが、testing-libraryです。 公式によると、testing-libraryは次のようなソリューションを提供するlibraryです。 The Solution The Testing Library family of libraries is a very light-weight solution for testing without all the implementation details. The main utilities it provides involve querying for nodes similarly to how users would find them. In this way, testing-library helps ensure your tests give you confidence in your UI code. ...

April 5, 2020 · derui

ProtocolBufferを使ってWebSocketでRPCをする

超暖冬だったりコロナウイルス騒ぎだったりと、なんと言うか全く落ち着かないこの頃、いかがお過ごしでしょうか。私は投資信託の金額が乱高下してなんとも言えない気持ちになっているのと、リーマンの再来とか言われてビクッとしている今日この頃です。 そういう世間の流れを一旦見ないことにして、最近やっと動作の確認が取れた、ProtocolBuffer + WebSocketによるRPCの方法を書こうかと思います。 <!–more–> さきにまとめ ここを見たら後の文は見なくていいんじゃないか疑惑が。 gRPCを利用しない場合、ブラウザと双方向でやり取りできるのはWebSocketくらい WebSocketではHTTP/2のようなpathは使えない JSON-RPCのような形式を使うとよい command的なもののEnumはデフォルト値をエラーとして使うといい 以降ではこれについての詳細を。 gRPCの利点と課題 ProtocolBufferを利用したRPCというと、gRPCがまっさきに出てきますし、ProtocolBufferを使う方の半分くらい(要出典)はこれが目的でしょう。ただし、それはgRPCを利用できる環境があるから、という前提が当然あります。 ではgRPCを利用できる条件とはどのようなものでしょうか。その大前提として、 HTTP/2 の存在があります。元々HTTP/2のベースであるSPDY自体、Googleが開発していたためでしょう。HTTP/2とHTTP/1.1の違いは次のようなものがあります。 HTTP/2はバイナリベース multiplexy Serverからクライアントに対してpushすることが出来る headerの圧縮が必須 gRPCは、これらのHTTP/2が持つ利点を活かして、高パフォーマンスかつ低遅延なRPCを実現しています。 間違いなく次世代のネットワークはHTTP/2ベースになると思いますが、OCamlではHTTP/2を利用する難易度がかなり高いです。また、ブラウザからJavaScriptを利用してHTTP/2接続を利用することも今は出来ません。 いま個人的に作っているツールでは、serverからのpushを必要としているので、HTTP/2が使えない場合、WebSocketを使うしかありません。しかし、WebSocketではgRPCを使うことは出来ません。 (gRPCは、HTTPのmethodやpathを利用して色々行っているため) WebSocketでRPCを実現しよう 改めて、WebSocketは以下のような特徴を持つprotocolです。 HTTPからのハンドシェイクをもって切り替える 一本のconnectionだけで通信を行う 双方向の通信が可能 完全に非同期 あるメッセージを待つ、というようなことは出来ない 参考:WebSocket Protocol仕様の日本語訳 しかし、JavaScriptでWebSocketを扱うプログラムを書いたことのある方はわかると思いますが、WebSocketは message という塊のやり取りしか出来ません。HTTP/1.1のようなpath/methodというようなものを使うことは出来ません。 RPCを実装する上では、そのメッセージがどのcommandに対するresponseなのか?を判別する必要があります。 ではどうするか?となりますが、ここで参考になるのが JSON-RPC です。 JSON-RPC自体、非常にLightな仕様ですが、大事なのが requestとresponseが完全に非同期である ということを前提としていることです。この特徴から、WebSocket上でも特に問題なく動作します。ということは、 JSON-RPCっぽいのをProtocolBufferで実装すればいいんではないか? という考えが浮かびます。 ProtocolBufferにJSON-RPCっぽいのを実装する では早速protoファイルを作ってみます。 syntax = "proto3"; enum Command { UNKNOWN_COMMAND= 0; FILER_INITIALIZE = 1; FILER_RELOAD_ALL= 2; FILER_MOVE_LOCATION= 3; FILER_UPDATED= 4; FILER_COPY_INTERACTION= 5; FILER_MOVE_INTERACTION= 6; FILER_DELETE_INTERACTION = 7; KEYMAP_ADD_KEY_BINDING= 8; KEYMAP_REMOVE_KEY_BINDING= 9; KEYMAP_GET = 10; KEYMAP_UPDATED = 11; } // common request message Request { string id = 1; Command command = 2; bytes payload = 3; } enum Status { UNKNOWN = 0; SUCCESS = 1; INVALID_REQUEST_PAYLOAD = 2; COMMAND_FAILED = 3; } message Error { int32 status = 1; string error_message = 2; } // common response. Field `id' must same value of the request. message Response { string id = 1; Status status = 2; bytes payload = 3; Error error = 4; } message SomeProcedureRequest { string fooBar = 0; } message SomeProcedureResponse { int32 count = 0; } service SampleService { rpc someProcedure(Request) returns (Response); } ポイントはいくつかありますが、特に大事だと感じたのは次の点です。 ...

March 15, 2020 · derui

hygen.ioでboilerplateを自動生成すると捗る話

閏年の閏日ということなので(?)、記事を書いておきます。特別な日にでも書いておかないとアウトプットがないので・・・。 今回は、最近使い始めて結構いい感じになってきた、hygen.ioについてです。 <!–more–> hygen.ioとは hygen.ioは、公式で以下のように紹介されています。 The scalable code generator that saves you time. 簡単に書くと、MavenとかGradleとかで初期構成を自動生成したり、create-react-appとかで生成したりといった、code generatorの一つです。 特徴としては 速度 と シンプルである ことで、複雑なDSLを覚える必要は特になく、簡単に使い始められます。また、後述する inject という機能のおかげで、自動生成しつつ、その情報を別ファイルに埋め込む、みたいなことが割と簡単です。 どんなprojectで使われてる? ここを見ると大体わかりそうです。JavaScript界隈での有名企業が入っていたりと、それなりに広く使われているようです。 なお、gulpとかnpm scriptとかMakefileでも出来るんちゃう?という気もしますし、実際出来ると思いますが、code generatorとして特化した機能を提供しているhygenを利用する方が、設定のごった煮になる可能性が低いかな・・・という気がします。 boilerplateを自動生成してみる 今個人で作業しているリポジトリでは、Reduxをmoduleという形で利用するとともに、多数のcommandというmoduleを生成する必要があります。ほとんどinterfaceだけは決まっているので、新しいcommandやmoduleを追加する度、同じようなファイルを生成したり、構造に気を使ったり・・・という作業が必要になります。 流石にこれはめんどくさい・・・となってきたので、hygenを利用していろいろ自動生成してみました。 hygen自体の使い方は公式サイトを見てもらったほうが良いと思いますので、リンクだけ貼っておきます。今回作ったgeneratorの構造はこんな感じです。 実際に使っているのはもうちょっと色々追加されています。 --+ _template |-+ module |-- help |-+ init | |-- actions-test.ejs.t | |-- actions.ejs.t | |-- index.ejs.t | |-- inject_reducer.ejs.t | |-- inject_import-module.ejs.t | |-- inject_action-type.ejs.t | |-- reducer-test.ejs.t | |-- reducer.ejs.t | |-- types.ejs.t |-- new-action これを使うと、こんな感じで新しいmoduleを追加したり、追加したmoduleに対して新しいactionを追加したり出来ます。 ...

February 29, 2020 · derui

polybarからi3blocksに乗り換えてみた

今年の冬は本当に暖冬で、今から今年の夏が心配です。水不足的な意味で。 時事ネタは置いといて、最近デスクトップのbarをpolybarからi3blockに移行したので、なんで移行したのかとかを書いておこうかと思います。 <!–more–> i3blocks i3blocksは、その説明にあるとおり、text-baseなstatus barです。polybarもだいたい同じような感じですね。これらの違いを個人的にあげてみます。 polybar feature rich 設定ファイルでだいたい何でもやる 組み込みで結構な量のmoduleがある i3blocks 本体機能は必要最小限 組み込みのmoduleはほぼ無い i3blocksは、組み込みmoduleとかがほぼない代わりに、moduleから返された結果を表示するだけ、というシンプルな形式に割り切っています。そのため、複雑化しやすい(個人の意見です)polybarよりも設定ファイルがシンプルになります。 polybarから乗り換えた理由 polybarは、その組み込みmoduleが多いことも相まって、コンパイル時の依存が多いです。出来るだけ依存を少なくしたいのと、利用しないmoduleが多かったというのもあり、他のstatus barを検討していました。 i3blocksは1.4まではデフォルトでmoduleを用意していましたが、1.5で大きく変更され、i3blocks本体は最小限で、moduleは全てi3blocks-contribに分割されています。(blockletと読んでいるようです)。このため、必要なものを自分でさっくり作るなり、必要なscriptだけを取得するとかが簡単です。 また、色とかもmodule内で出力することで個別に変更できるため、別ファイルにまとめておいて読み出す、とかもできます。configにまとめるのとどっちがいいか、というのはありますが・・・。 i3blocksの設定 color=#8fa1b3 [title] command=~/.config/i3blocks/scripts/title.sh interval=persist [uptime] label= command=uptime | sed 's/.*up \([^,]*\),.*/\1/' interval=60 [memory] label= command=~/.config/i3blocks/scripts/memory.sh interval=1 [load average] label= command=echo "$(uptime | sed 's/.*load average: \(.*\)/\1/' | cut -d, -f1)/$(grep 'processor' /proc/cpuinfo | wc -l)" interval=1 [date] label= command=echo " $(date '+%Y/%m/%d %H:%M(%a)')" interval=1 [power] label= command=~/.config/i3blocks/scripts/power.sh interval=persist [separator] 実際に使っているconfigです。polybarと違い、各moduleの設定は同一で、違うのはcommandとかintervalの中身だけ、という統一感がいい感じです。 ...

February 21, 2020 · derui

Domain Modeling Made Functionalを読んだ

個人的に作っているツールで、OCamlでどうやってDDDをやっていくか?ということを考える中で、 Domain Modeling Made Functionalというそのものズバリな本の存在を知りました。そこまで高くなかったので購入して読んでみたので、感想を書いてみます。 <iframe style=“width:120px;height:240px;” marginwidth=“0” marginheight=“0” scrolling=“no” frameborder=“0” src="//rcm-fe.amazon-adsystem.com/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=derui09-22&language=ja_JP&o=9&p=8&l=as4&m=amazon&f=ifr&ref=as_ss_li_til&asins=1680502549&linkId=05192cc54dff2d67c58d290cad5cdd28"></iframe> <!–more–> どんな内容? すごい簡単に書くと、 F#でDDDをやっていく時のノウハウが詰まっている 本です。たいていこういう本はScalaとかHaskellで書かれている印象(偏見)なので、F#というのが中々ニッチな印象でした。 ちなみにF#を知らない方のために紹介だけしておくと、F#は以下のような特徴を持つ言語です。 OCamlをベースにした関数型言語 ベースにしているので、命名規則とか文法とかは違いますが、ML族です なので、型クラスとかはありません .NET Platform上で動く 多分.NET Coreでも動くんではないでしょうか OCamlを使っている人間としては、F#の文法は若干の違和感を感じるくらいで、特に読みづらさとかは感じませんでした。 もうちょっと細かい内容 概ね、以下順で進んでいきます。 DDD自体の解説 仮想プロジェクトを使ったDomain導出の流れ この部分が、対話形式になっていてなかなか面白いです。また、ダイアグラムなどをあえて使わず、擬似言語を用いてユビキタス言語やビジネスの制約とかを書き下しているのが印象的でした。やってみたい ドメインをどうやって型に翻訳していくか ここからが関数型言語(特に代数的データ型を持つ言語)でどうやってドメインを型にしていくか、という話題です。この時点では実装を一切考えず、ビジネス要件を型の表現力でどう表現するか?に注力しています。 ワークフローをどう表現するか ビジネス上のワークフローを、小さいstepという関数で表現していくか、という内容です。ここでも実装そのものは行わず、step/work flowをひたすら型で表現していきます。 型に対する実装 ドメイン自体、そしてワークフローに対して行った大量の型をどのようにつなぎ合わせていくか、という内容です。ここから実装が登場します。バリデーションやエラーを扱う話題もあります。 関数でワークフローを表現した時、stepの依存などをどのように扱うか、という内容もあります。関数適用をDependency Injectionとして利用するなど、関数型言語で一般的なテクニックなども紹介しています。 エラー実装、永続化、シリアライズなど現実的な内容それぞれ独立した章に分かれていますが、全て実装に関する内容です。 エラーでは、主にResultをどう扱うか、Resultをどう繋げていくか、といった実践的な内容となっています。永続化、シリアライズでは、DBやJSONへのシリアライズなど、主にWebアプリケーションで扱いそうな内容を多く扱っています。 特に印象に残った点 DDDに当たる部分は、Evans本やIDDD本を読んでいれば、ある程度は読み飛ばしてしまっていいと思います。そこ以外で印象に残っていたり、参考になったものがいくつかあります。 とにかく型で表現する 文中には、必要に応じて減らしてもいい、という書き方をしています しかし、step/work flowすら型で表現する、というのか魅力的です IDとかは、実際にはfunctorで作ったり、ある程度自動的に導出することも出来るので、方はある程度多めになってもなんとかなる気はします Monadは必ずしも必要ではない 実際、文中ではMonadという言葉をほとんど使っていません 言及している部分では、 それほど恐れる必要はない という記述になっています Free Monadなどにも触れているので、実際のアプリケーションなどでは使うかもね・・・というニュアンスなのかもしれません 関数適用はDI 最近オブジェクト指向言語ばかりやっているのと、部分適用して使う、というのが普通すぎて、逆に目からウロコでした IOはEdgeに追いやる DomainはIOを知るべきではない、というのを何度も書いています Clean Architecture/Onion Architecture/Hexagonal Architectureといったアーキテクチャをより簡潔に言い表したものだなーって思います Edgeにどうやって追いやる?関数を使えよ、という当たり前の内容もちゃんと書いてくれています 最近OCamlで書いていると、なんとなくFunctorを使ってしまう部分でも、より基本的な関数をまず使おう、と思い直しました DTOをきっちり使う重要さ Domainを直接JSONなどに変換してはならない理由をちゃんと説明している点が非常に良かったです 個人的にもDomainをそのままAPIなどに露出しないようにしていますが、次からは何故そうするのか?と説得できそうな気がします 現実だと工数がかかりすぎる、とか言われそうですが・・・ 型パズルの解き方 大量の型が出てきた時に、どのように関数を繋げていくか、という方法論が書かれています 関数型言語でもDDDをやりたい人にはオススメです DDDをJavaとかC#、他の言語ではやっているけど、関数型言語ではどうやるんだろう、Monadとかよくわからない概念のオンパレードになるんじゃないか、とか思っている人にオススメです。 ...

February 7, 2020 · derui

Protocol BuffersとJSONの扱い in OCaml

以前の記事で、ProtocolBuffersでOCaml/TypeScript間の定義を作成して色々やっていたのですが、いくつか問題が出てきたので書いてみます。 <!–more–> ocaml-protoc-pluginに乗り換えた 前回は ocaml-protocを使いましたが、ocaml-protoc-pluginに乗り換えました。理由としては以下となります。 標準のprotocにおけるpluginという形での提供 自前で解析していてもいいとは思いますが、他のproductではprotocのplugin形式が多かったので 型定義にannotationを付けられる yojsonとかに変換するのが簡単です ts-protoc-gen + protoc標準から、pbjs(protobufjs)に乗り換えた 前はprotocに標準添付されているJavaScript実装と、ts-protoc-genを組み合わせていたのですが、以下のような問題があったので乗り換えました。 Jsonからの変換とかが出来ない protocの標準では、 protocolbuffers以外に対するserialize/deserializeがありません JSON-RPCを利用しているので、軽く絶望しながら切り替えました(先に調べろと 発生した問題 今作っているapplicationでは、Electronとbackend server間をWebsocketでつなぎ、RPCとしてJSON-RPCを利用しています。この構成、面倒ではありますが、割と使い勝手がよいのです。しかし、protoファイルから生成した型を使っていると、困る割にいい解決策が無い問題にあたりました。 その問題とは、 OCamlでの型定義とProtocolBufferでの型定義との互換性 です。ナンノコッチャですが、要はocaml-protoc-pluginが生成してくれる型と、protocol_conv_jsonのでのJSON変換が一筋縄では行かない、ということです。 私は大きく2つの問題にあたりましたが、そのうちの一つを例に上げます。 enum Types { Unknown = 0; String = 1; Number = 2; } message Foo { Types value = 0 } こんな感じのprotoファイルからOCamlの定義を作成すると、以下のような感じになります(moduleの定義は省略しています)。 open Ocaml_protoc_plugin.Runtime [@@warning "-33"] module rec Types : sig type t = Unknown | String | Number val to_int: t -> int val from_int: int -> (t, [> Runtime'.Result.error]) result end and Foo : sig val name': unit -> string type t = Types.t val to_proto: t -> Runtime'.Writer.t val from_proto: Runtime'.Reader.t -> (t, [> Runtime'.Result.error]) result end ここでポイントとなるのが、protoファイルにおいてenumと定義した部分と、OCaml版におけるTypes moduleです。OCamlにおいては、Enumを代数的データ型として表すのはごく自然だと思うのですが、問題はProtocol Buffersにおいては、enumは 単なる数値 でしかありません。 to_int とかがそれを物語っています。 ...

January 13, 2020 · derui

OCamlとTypeScriptをProtocal Buffersでつないでみる

気づいたら来週で今年の業務も終わりということに気づきました。今年もいろいろ・・・あったか? 今回は、最近色々と辛くなってきたので、初めてProtocol Buffers・・・というかProtocol Buffers languageを利用して、サーバー側=OCamlとクライアント側=TypeScriptで型定義を共有していきたいと思います。 ...

December 22, 2019 · derui

OCamlの開発環境2019末

この記事は株式会社オープンストリームアドベントカレンダーの3日目の記事です。 年の瀬ということで、いい感じに部屋が冷えてきてちょうどよいです。さて、 あまりネタがない 今回はOCamlの開発環境について書こうかと思います。 ...

December 3, 2019 · 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