<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>yewton.net</title><link>https://www.yewton.net/</link><atom:link href="https://www.yewton.net/index.xml" rel="self" type="application/rss+xml"/><description>yewton.net</description><generator>Hugo Blox Builder (https://hugoblox.com)</generator><language>ja</language><lastBuildDate>Mon, 12 Jan 2026 00:20:00 +0900</lastBuildDate><image><url>https://www.yewton.net/media/sharing.png</url><title>yewton.net</title><link>https://www.yewton.net/</link></image><item><title>Agent Client Protocol を理解する</title><link>https://www.yewton.net/2026/01/12/agent-client-protocol/</link><pubDate>Mon, 12 Jan 2026 00:20:00 +0900</pubDate><guid>https://www.yewton.net/2026/01/12/agent-client-protocol/</guid><description>&lt;div class="ox-hugo-toc toc"&gt;
&lt;div class="heading"&gt;&amp;#30446;&amp;#27425;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#%e3%81%af%e3%81%98%e3%82%81%e3%81%ab"&gt;はじめに&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e8%83%8c%e6%99%af-%e3%81%aa%e3%81%9c-acp-%e3%81%8c%e5%bf%85%e8%a6%81%e3%81%aa%e3%81%ae%e3%81%8b"&gt;背景: なぜ ACP が必要なのか&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e4%b8%bb%e3%81%aa%e7%89%b9%e5%be%b4%e3%81%a8%e3%82%b3%e3%83%b3%e3%82%bb%e3%83%97%e3%83%88"&gt;主な特徴とコンセプト&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e5%ae%9f%e8%b7%b5-agent-shell-dot-el-%e3%81%a7%e3%81%ae%e5%88%a9%e7%94%a8%e4%be%8b"&gt;実践: &lt;code&gt;agent-shell.el&lt;/code&gt; での利用例&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#initialization"&gt;Initialization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#session-setup"&gt;Session Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#prompt-turn"&gt;Prompt Turn&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e5%b0%86%e6%9d%a5%e6%80%a7"&gt;将来性&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#github-copilot-cli-%e3%81%a7%e3%81%ae%e3%82%b5%e3%83%9d%e3%83%bc%e3%83%88"&gt;GitHub Copilot CLI でのサポート&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e3%83%89%e3%83%a9%e3%83%95%e3%83%88%e4%bb%95%e6%a7%98%e3%81%ae%e5%b1%95%e6%9c%9b"&gt;ドラフト仕様の展望&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e3%81%be%e3%81%a8%e3%82%81"&gt;まとめ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;!--endtoc--&gt;
&lt;h2 id="はじめに"&gt;はじめに&lt;/h2&gt;
&lt;p&gt;Agent Client Protocol (ACP) は、AI エージェントとクライアント（エディタなど）が対話する際の標準を定義するプロトコルです。
この記事では、ACP の概要と、その背景や具体的な利用例、そして将来性について、自身の理解を元に解説します。&lt;/p&gt;
&lt;p&gt;公式ドキュメントは &lt;a href="https://agentclientprotocol.com/overview/introduction" target="_blank" rel="noopener"&gt;こちら&lt;/a&gt; にあります。&lt;/p&gt;
&lt;h2 id="背景-なぜ-acp-が必要なのか"&gt;背景: なぜ ACP が必要なのか&lt;/h2&gt;
&lt;p&gt;2025年8月30日、 Zed から以下のように発表がありました:&lt;/p&gt;
&lt;blockquote class="twitter-tweet"&gt;&lt;p lang="en" dir="ltr"&gt;This week, we announced ACP, an open-source protocol that standardizes communication between clients and coding agents, but we also released Zed v0.201! Let&amp;#39;s dive into some of the highlights!&lt;a href="https://t.co/dHIcUWRNUs"&gt;https://t.co/dHIcUWRNUs&lt;/a&gt;&lt;/p&gt;&amp;mdash; Zed (@zeddotdev) &lt;a href="https://twitter.com/zeddotdev/status/1961502810068979799?ref_src=twsrc%5Etfw"&gt;August 29, 2025&lt;/a&gt;&lt;/blockquote&gt; &lt;script async src="https://platform.twitter.com/widgets.js" charset="utf-8"&gt;&lt;/script&gt;
&lt;p&gt;同年10月7日には、 JetBrains から Zed と連携して ACP に取り組むことが発表されました:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.jetbrains.com/ai/2025/10/jetbrains-zed-open-interoperability-for-ai-coding-agents-in-your-ide/" target="_blank" rel="noopener"&gt;JetBrains × Zed: Open Interoperability for AI Coding Agents in Your IDE | The JetBrains AI Blog&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;同年12月5日に発表された &lt;a href="https://blog.jetbrains.com/ai/2025/12/bring-your-own-ai-agent-to-jetbrains-ides/#behind-the-closed-doors" target="_blank" rel="noopener"&gt;Bring your own AI agent to JetBrains IDEs | The JetBrains AI Blog&lt;/a&gt; で語られているところによると、JetBrains が自社エージェント統合用のプロトコルを公開しようとしたタイミングで Zed も同様の動きを見せていたため、
規格の乱立を避けるべく協力することになった、というのが実情のようです。&lt;/p&gt;
&lt;p&gt;当初から『業界標準』を目指して周到に計画されたものではなく、各社の実利的なニーズが合致した結果として生まれた、という経緯は興味深い点です。
各ベンダーが「エージェントを効率よく統合したい」という現実的な課題を持っていたタイミングが重なったことが、結果として標準化を加速させたと言えるでしょう。&lt;/p&gt;
&lt;p&gt;LSP (Language Server Protocol) がプログラミング言語ごとの開発体験の差異を吸収したように、ACP は乱立する AI エージェントとそのクライアント間の通信を標準化することを目指しています。&lt;/p&gt;
&lt;h2 id="主な特徴とコンセプト"&gt;主な特徴とコンセプト&lt;/h2&gt;
&lt;p&gt;ACP は、タスクの実行、進捗の報告、対話的なデータ交換など、エージェントとのやり取りに必要な一連の機能を定義しています。&lt;/p&gt;
&lt;p&gt;具体的な仕様は &lt;a href="https://agentclientprotocol.com/overview/introduction" target="_blank" rel="noopener"&gt;公式サイト&lt;/a&gt; を見れば分かりますが、ざっくり以下のような流れになっています:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Initialization
&lt;ul&gt;
&lt;li&gt;接続の確立や、ベンダーの認証処理&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Session Setup
&lt;ul&gt;
&lt;li&gt;新規セッションを始めるか、既存セッションを復元する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Prompt Turn
&lt;ul&gt;
&lt;li&gt;ここから実際のやりとりループが始まる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;公式サイトの構成は Protocol 配下が全部並列で分かりづらいですが、
まず Initialization, Session Setup, Prompt Turn が Overview で述べられている上記のメッセージフローに対応しています。&lt;/p&gt;
&lt;p&gt;Schema はその通りスキーマ定義で、それ以外は個々のコンセプトの説明になっています。&lt;/p&gt;
&lt;h2 id="実践-agent-shell-dot-el-での利用例"&gt;実践: &lt;code&gt;agent-shell.el&lt;/code&gt; での利用例&lt;/h2&gt;
&lt;p&gt;ACP の具体的な動作を理解するために、Emacs のクライアント実装である &lt;a href="https://github.com/simon-katz/agent-shell" target="_blank" rel="noopener"&gt;agent-shell.el&lt;/a&gt; を使って、実際の通信内容を見ていきます。&lt;/p&gt;
&lt;p&gt;ここでは、エディタ上で範囲を指定して、その範囲の内容を日本語に翻訳し、挿入してもらう、という簡単なタスクをエージェントに依頼し、その際の ACP メッセージ（リクエストとレスポンス）をキャプチャして、プロトコルの使われ方を具体的に示します。&lt;/p&gt;
&lt;p&gt;ログ出力の有無は &lt;code&gt;agent-shell-toggle-logging&lt;/code&gt; で設定出来ます。
日本語を含むプロンプトの場合は &lt;code&gt;agent-shell-prompt-compose&lt;/code&gt; で専用のバッファを設けるのがよいでしょう。&lt;/p&gt;
&lt;p&gt;エージェントには &lt;a href="https://geminicli.com/" target="_blank" rel="noopener"&gt;Gemini CLI&lt;/a&gt; を使います ( &lt;code&gt;--experimental-acp&lt;/code&gt; )。&lt;/p&gt;
&lt;h3 id="initialization"&gt;Initialization&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;agent-shell&lt;/code&gt; の場合、最初に何らかのプロンプトを送信すると、初期化フェーズが始まります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;jsonrpc&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;initialize&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;params&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;protocolVersion&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;clientCapabilities&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;fs&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;readTextFile&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;writeTextFile&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ファイルの読み書きが出来ることを宣言していますね。&lt;/p&gt;
&lt;p&gt;このリクエストを受けて、エージェント側から初期化のための応答が返ります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;jsonrpc&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;result&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;protocolVersion&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;authMethods&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;oauth-personal&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Log in with Google&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;gemini-api-key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Use Gemini API key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Requires setting the `GEMINI_API_KEY` environment variable&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;vertex-ai&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Vertex AI&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;agentCapabilities&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;loadSession&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;promptCapabilities&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;image&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;audio&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;embeddedContext&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;認証方法のリストに加えて、エージェント側の対応機能が返ってきています。&lt;/p&gt;
&lt;p&gt;Gemini CLI は今のところセッションの永続化には対応していないようです。画像やオーディオをプロンプトとして埋め込むことが出来ることも分かります。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;agent-shell&lt;/code&gt; の動きとしては現在のところ &lt;code&gt;agent-shell-google-authentication&lt;/code&gt; に従って&lt;a href="https://github.com/xenodium/agent-shell/blob/91c518a5e78ced0e5810035519160059f2c1eebc/agent-shell-google.el#L129-L158" target="_blank" rel="noopener"&gt;固定値を返すような実装&lt;/a&gt;になっており、応答内容は使っていません ( TODO になっています )。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;jsonrpc&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;authenticate&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;params&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;methodId&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;oauth-personal&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;authMethod&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;oauth-personal&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Log in with Google&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;エージェントは成功を示すために以下のような空レスポンスを返します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;jsonrpc&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;result&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;他の操作でも、特に返すべきものが無い場合はこのような空レスポンスで成功を表現するようです。&lt;/p&gt;
&lt;h3 id="session-setup"&gt;Session Setup&lt;/h3&gt;
&lt;p&gt;初期化に成功したらセッションを開始します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;jsonrpc&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;session/new&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;params&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;cwd&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/path/to/cwd/&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;mcpServers&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;セッションというのは特定のディレクトリに関連づけられる、ということが分かりますね。&lt;/p&gt;
&lt;p&gt;エージェントはリクエストを受けて、セッション ID を返します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;jsonrpc&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;result&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;sessionId&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;36702bdd-86f6-4e87-b964-c2328216f375&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;以降のやりとりはこのセッション ID がキーとなります。&lt;/p&gt;
&lt;h3 id="prompt-turn"&gt;Prompt Turn&lt;/h3&gt;
&lt;p&gt;ここから、入力したプロンプトの処理が始まります。&lt;/p&gt;
&lt;p&gt;選択範囲を作成した状態で &lt;code&gt;agent-shell-prompt-compose&lt;/code&gt; を呼ぶと、該当箇所への参照をプロンプトに自動で含めてくれます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;jsonrpc&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;session/prompt&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;params&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;sessionId&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;36702bdd-86f6-4e87-b964-c2328216f375&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;prompt&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;以下を日本語に翻訳して:\n\ncontent-org/content-org/all-posts.org:1614-1614&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;翻訳を頼んでみました。すると、以下のようにまずエージェントの思考が &lt;code&gt;agent_thought_chunk&lt;/code&gt; として返ってきました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;jsonrpc&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;session/update&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;params&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;sessionId&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;36702bdd-86f6-4e87-b964-c2328216f375&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;update&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;sessionUpdate&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;agent_thought_chunk&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;**Examining the File&amp;#39;s Contents**\n\nI&amp;#39;m now reading the file around line 1614 to grasp the full context. This step is crucial for accurate translation and the subsequent `replace` operation. It allows me to pinpoint the text requiring translation and prepare the `old_string` for the `replace` tool.\n\n\n&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;該当の部分を読みたいぞ、となっているようです。その思考の結果、 &lt;code&gt;agent_message_chunk&lt;/code&gt; として応答が返ってきました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;jsonrpc&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;session/update&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;params&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;sessionId&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;36702bdd-86f6-4e87-b964-c2328216f375&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;update&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;sessionUpdate&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;agent_message_chunk&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;I will read the file `sample.txt` around line 10 to identify the text to translate.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;翻訳するために該当部分を読みます、という宣言です。&lt;/p&gt;
&lt;p&gt;(何故か突然英語になってますが、これは Gemini の癖でしょう…)&lt;/p&gt;
&lt;p&gt;この宣言のあと、ファイルを読むためのツール実行が始まります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;jsonrpc&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;session/update&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;params&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;sessionId&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;36702bdd-86f6-4e87-b964-c2328216f375&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;update&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;sessionUpdate&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;tool_call&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;toolCallId&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;read_file-1767793979301&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;in_progress&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;title&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;content-org/all-posts.org&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;locations&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;path&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/home/yewton/Projects/yewton.net/content-org/all-posts.org&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;line&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1610&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;kind&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;read&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;この時点では ACP の &lt;code&gt;fs/read_text_file&lt;/code&gt; は使われないようです。
つまり、エディタの機能ではなくエージェント自身のツールを実行しようとしています
( これは恐らく今回の Gemini の挙動はそうなっていた、というだけだと思います )。&lt;/p&gt;
&lt;p&gt;ツールの実行後、翻訳対象の文章を特定出来たので、翻訳と編集を行う宣言が返ってきました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;jsonrpc&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;session/update&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;params&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;sessionId&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;36702bdd-86f6-4e87-b964-c2328216f375&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;update&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;sessionUpdate&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;agent_message_chunk&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;「こんにちは、世界！」に翻訳して、次の段落に追加します。&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://agentclientprotocol.com/protocol/file-system#writing-files" target="_blank" rel="noopener"&gt;fs/write_text_file&lt;/a&gt; には、行番号など書き込み範囲を特定する仕様が定義されておらず、
対象のファイルパスと、上書き内容だけを指定出来るようです。&lt;/p&gt;
&lt;p&gt;その為、書き込みの前にまず全文を読み込む必要があります。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;jsonrpc&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;fs/read_text_file&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;params&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;path&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/home/yewton/Projects/yewton.net/content-org/all-posts.org&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;sessionId&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;36702bdd-86f6-4e87-b964-c2328216f375&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;line&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;limit&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;書き込みに伴う読み込みには &lt;code&gt;fs/read_text_file&lt;/code&gt; が使われる模様です。
つまり、エディタ上で編集途中でもその内容は失われない、ということになるので合理的な選択でしょう
( 本来は翻訳対象の特定時も、同様にした方が良さそうですが… )。&lt;/p&gt;
&lt;p&gt;実際に書き込む内容を確定させると、以下のように書き込みの許可を求めるリクエストがエージェントから送られます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;jsonrpc&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;session/request_permission&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;params&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;sessionId&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;36702bdd-86f6-4e87-b964-c2328216f375&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;options&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;optionId&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;proceed_always&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Allow All Edits&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;kind&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;allow_always&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;optionId&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;proceed_once&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Allow&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;kind&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;allow_once&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;optionId&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;cancel&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Reject&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;kind&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;reject_once&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;toolCall&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;toolCallId&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;replace-1767793984780&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;pending&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;title&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;content-org/all-posts.org: Hello, World! =&amp;gt; Hello, World!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;diff&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;path&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;all-posts.org&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;oldText&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;newText&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;...&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;locations&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;path&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/home/yewton/Projects/yewton.net/content-org/all-posts.org&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;kind&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;edit&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;この応答を受けると以下のような確認ダイアログが出てきます。&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2026/01/12/agent-client-protocol/Screenshot_2026-01-07_22-56-04.png"&gt;
&lt;/figure&gt;
&lt;p&gt;( 一度ダイアログを閉じてしまったので再度表示して試したい、という流れの応答だったので上記のような内容になっていますが気にしないでください 🙇 )&lt;/p&gt;
&lt;p&gt;ここで &lt;code&gt;View&lt;/code&gt; を選択すると、以下のように変更内容をプレビュー出来ます。&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2026/01/12/agent-client-protocol/Screenshot_2026-01-07_22-57-12.png"&gt;
&lt;/figure&gt;
&lt;p&gt;プロトコル上は diff 形式でやりとりされているわけではなく、更新前後の全文が送られているので、この表示はエディタ側で行うことが求められています。&lt;/p&gt;
&lt;p&gt;ここで &lt;code&gt;y&lt;/code&gt; を押して許可すると、以下のような応答がエージェントに返されます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;:direction outgoing
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;:kind response
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;:object
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; jsonrpc 2.0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; id 5
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; result
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; outcome
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; outcome selected
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; optionId proceed_once
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;( クライアントからの応答の場合は生ログが出力されていなかったのでこのような形で…。
&lt;a href="https://github.com/xenodium/acp.el/blob/7b67facc657a7388a53ea8bba5d6e7eba20fa3e0/acp.el#L371-L387" target="_blank" rel="noopener"&gt;acp&amp;ndash;response-sender&lt;/a&gt; で &lt;code&gt;acp--log&lt;/code&gt; の呼び出しが漏れているだけだと思われます。 )&lt;/p&gt;
&lt;p&gt;許可を得たので、改めて読み込むようです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;jsonrpc&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;fs/read_text_file&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;params&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;path&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/home/yewton/Projects/yewton.net/content-org/all-posts.org&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;sessionId&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;36702bdd-86f6-4e87-b964-c2328216f375&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;line&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;limit&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;そして、 &lt;a href="https://agentclientprotocol.com/protocol/file-system" target="_blank" rel="noopener"&gt;fs/write_text_file&lt;/a&gt; で書き込みます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;jsonrpc&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;fs/write_text_file&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;params&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;path&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/home/yewton/Projects/yewton.net/content-org/all-posts.org&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;...ファイルの中身全量...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;sessionId&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;36702bdd-86f6-4e87-b964-c2328216f375&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;このように全量を一括書き込みするようなので、あまりにも大きいファイルだと注意が必要かもしれません
( エディタ上で開いて編集出来ている時点で、ほぼ問題無いとは思いますが )。&lt;/p&gt;
&lt;h2 id="将来性"&gt;将来性&lt;/h2&gt;
&lt;p&gt;ACP は発表されたばかりの発展途上プロトコルであるとは思いますが、一過性のブームとはならず、今後の展望も明るいんではないかと考えています。&lt;/p&gt;
&lt;p&gt;まずは先に述べたように、 JetBrains と Zed という、クライアント( エディタ ) 側の大きなプレイヤーが牽引しているということ。&lt;/p&gt;
&lt;p&gt;Visual Studio Code にも以下 Issue が立てられており、盛り上がりを見せています。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/microsoft/vscode/issues/265496" target="_blank" rel="noopener"&gt;Add support in vscode for Agent Client Protocol (ACP) #265496&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;そして、人間がエージェントの対面にいる限りは、人間のツールであるエディタを通じたやりとりを形式化・標準化することは今後も求められていくでしょう。&lt;/p&gt;
&lt;p&gt;以下、具体的に将来起こりそうなことについてピックアップして取り上げます。&lt;/p&gt;
&lt;h3 id="github-copilot-cli-でのサポート"&gt;GitHub Copilot CLI でのサポート&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://github.com/github/gh-copilot" target="_blank" rel="noopener"&gt;GitHub Copilot CLI&lt;/a&gt; には、まだ公式ドキュメントやコマンドの help にも記載されていませんが、ACP を利用するための &lt;code&gt;--acp&lt;/code&gt; オプションが実験的に追加されているようです( 2026年1月12日現在 )。&lt;/p&gt;
&lt;p&gt;agent-shell では以下のように設定すると動かせます ( &lt;code&gt;--acp&lt;/code&gt; フラグが肝 )。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-emacs-lisp" data-lang="emacs-lisp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cl-defun&lt;/span&gt; &lt;span class="nv"&gt;agent-shell-gh-copilot-make-client&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;&amp;amp;key&lt;/span&gt; &lt;span class="nv"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;Create an GitHub Copilot client using BUFFER as context.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;unless&lt;/span&gt; &lt;span class="nv"&gt;buffer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ne"&gt;error&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Missing required argument: :buffer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;agent-shell--make-acp-client&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;:command&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;copilot&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;:command-params&lt;/span&gt; &lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;--acp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;:environment-variables&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;:context-buffer&lt;/span&gt; &lt;span class="nv"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;agent-shell-gh-copilot--welcome-message&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;Return GitHub Copilot welcome message using &lt;/span&gt;&lt;span class="ss"&gt;`shell-maker&amp;#39;&lt;/span&gt;&lt;span class="s"&gt; CONFIG.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;let&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;art&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;agent-shell--indent-string&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;agent-shell-gh-copilot--ascii-art&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;string-trim-left&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;shell-maker-welcome-message&lt;/span&gt; &lt;span class="nv"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;\n\n&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;art&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;\n\n&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;agent-shell-gh-copilot--ascii-art&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;GitHub Copilot ASCII art.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;let*&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;is-dark&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;eq&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;frame-parameter&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;background-mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;dark&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;text&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;string-trim&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;┌── ──┐
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;│ ▄██████▄ │
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; Welcome to GitHub ▄█▀▀▀▀▀██▀▀▀▀▀█▄
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; █████┐ █████┐ █████┐ ██┐██┐ █████┐ ██████┐ ▐█ ▐▌ █▌
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; ██┌───┘██┌──██┐██┌─██┐██│██│ ██┌──██┐└─██┌─┘ ▐█▄ ▄██▄ ▄█▌
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; ██│ ██│ ██│█████┌┘██│██│ ██│ ██│ ██│ ▄▄███████▀▀███████▄▄
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; ██│ ██│ ██│██┌──┘ ██│██│ ██│ ██│ ██│ ████ ▄ ▄ ████
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; └█████┐└█████┌┘██│ ██│██████┐└█████┌┘ ██│ ████ █ █ ████
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; └────┘ └────┘ └─┘ └─┘└─────┘ └────┘ └─┘ ▀███▄ ▄███▀
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;│ ▀▀████████████▀▀ │
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;└── ──┘
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;&amp;#34;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;propertize&lt;/span&gt; &lt;span class="nv"&gt;text&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;font-lock-face&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;if&lt;/span&gt; &lt;span class="nv"&gt;is-dark&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;:foreground&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;#4a9eff&amp;#34;&lt;/span&gt; &lt;span class="nb"&gt;:inherit&lt;/span&gt; &lt;span class="nv"&gt;fixed-pitch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;:foreground&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;#2563eb&amp;#34;&lt;/span&gt; &lt;span class="nb"&gt;:inherit&lt;/span&gt; &lt;span class="nv"&gt;fixed-pitch&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;agent-shell-agent-configs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;agent-shell-opencode-make-agent-config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;agent-shell-google-make-gemini-config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;agent-shell-make-agent-config&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;:mode-line-name&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;GitHub Copilot&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;:buffer-name&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;GitHub Copilot&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;:shell-prompt&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;copilot&amp;gt; &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;:shell-prompt-regexp&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;copilot&amp;gt; &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;:welcome-function&lt;/span&gt; &lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;agent-shell-gh-copilot--welcome-message&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;:client-maker&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;agent-shell-gh-copilot-make-client&lt;/span&gt; &lt;span class="nb"&gt;:buffer&lt;/span&gt; &lt;span class="nv"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;:install-instructions&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;See TBW for installation.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="callout flex px-4 py-3 mb-6 rounded-md border-l-4 bg-blue-100 dark:bg-blue-900 border-blue-500"
data-callout="note"
data-callout-metadata=""&gt;
&lt;span class="callout-icon pr-3 pt-1 text-blue-600 dark:text-blue-300"&gt;
&lt;svg height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&gt;&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="m16.862 4.487l1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8l.8-2.685a4.5 4.5 0 0 1 1.13-1.897zm0 0L19.5 7.125"/&gt;&lt;/svg&gt;
&lt;/span&gt;
&lt;div class="callout-content dark:text-neutral-300"&gt;
&lt;div class="callout-title font-semibold mb-1"&gt;Note&lt;/div&gt;
&lt;div class="callout-body"&gt;&lt;p&gt;なお、 Gemini CLI もそうですが GitHub Copilot も &lt;a href="https://agentclientprotocol.com/protocol/draft/schema#session%2Fset_model" target="_blank" rel="noopener"&gt;session/set_model&lt;/a&gt; ( agent-shell 的には &lt;code&gt;default-model-id&lt;/code&gt; )には現時点で対応していません。&lt;/p&gt;
&lt;p&gt;Claude Code など一部のエージェントは対応しており、半分デファクトスタンダードのようですが、プロトコル上はまだ未定義であり &lt;code&gt;UNSTABLE&lt;/code&gt; とされています。&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;将来的には Copilot も ACP 準拠のエージェントとして、様々なクライアントから統一的に利用できるようになる可能性があります。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/github/copilot-cli/issues/222" target="_blank" rel="noopener"&gt;Support for ACP (Agent Client Protocol) #222&lt;/a&gt; をウォッチしましょう。&lt;/p&gt;
&lt;h3 id="ドラフト仕様の展望"&gt;ドラフト仕様の展望&lt;/h3&gt;
&lt;p&gt;現在議論されているドラフト仕様の中でも、特に以下の 2 つはエージェントの能力を最大限に引き出すことに寄与しそうです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://agentclientprotocol.com/rfds/session-fork" target="_blank" rel="noopener"&gt;Forking of existing sessions&lt;/a&gt;&lt;/strong&gt;: 既存のセッションを複製し、異なるコンテキストでタスクを並行実行させる機能。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://agentclientprotocol.com/rfds/proxy-chains" target="_blank" rel="noopener"&gt;Agent Extensions via ACP Proxies&lt;/a&gt;&lt;/strong&gt;: クライアントとエージェント間に新たに設けられるプロキシによる柔軟な機能拡張の仕組み。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらの機能は、&lt;a href="https://agentskills.io/home" target="_blank" rel="noopener"&gt;Agent Skills&lt;/a&gt; のような外部スキルセットとの連携や、特定のタスクに特化したサブエージェントの活用といった、より高度なエージェントアーキテクチャの規範を定義するものになると思います。&lt;/p&gt;
&lt;p&gt;特定のベンダーにロックインされない AI エージェントの利活用に必須のものになっていくのではないでしょうか。
もし仮に利用が必須でなくとも、その概念を理解することは有用なはずです。&lt;/p&gt;
&lt;h2 id="まとめ"&gt;まとめ&lt;/h2&gt;
&lt;p&gt;Agent Client Protocol は、AI エージェントを利用した開発の未来を具体化するプロトコルです。
AI エージェントとは何か、何が出来る必要があるのか、また今後何が出来るようになることを求められていくのかをキャッチアップする為に、ウォッチしていく価値のあるものだと考えています。&lt;/p&gt;</description></item><item><title>完全爆弾解除マニュアルのマニュアルPDFをいい感じに印刷する、または Ubuntu で小冊子印刷をする方法</title><link>https://www.yewton.net/2025/12/11/ubuntu-booket-printing-pdfbook2/</link><pubDate>Thu, 11 Dec 2025 22:00:00 +0900</pubDate><guid>https://www.yewton.net/2025/12/11/ubuntu-booket-printing-pdfbook2/</guid><description>&lt;h2 id="tl-dr"&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;Ubuntu 24.04 (Noble) で PDF を小冊子 (Booklet) 印刷用に加工するには、 &lt;code&gt;pdfbook2&lt;/code&gt; が便利。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# pdfbook2 は texlive-extra-utils に含まれる&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ディスク容量に注意（後述）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install texlive-extra-utils
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 変換&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pdfbook2 KeepTalkingAndNobodyExplodes-BombDefusalManual-v1-ja.pdf
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# -&amp;gt; KeepTalkingAndNobodyExplodes-BombDefusalManual-v1-ja-book.pdf が生成される&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これで生成された PDF を「長辺とじ」で両面印刷すれば、中綴じ可能な小冊子として印刷されます。&lt;/p&gt;
&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;p&gt;息子が誕生日に &lt;a href="https://amzn.to/4oDjvg4" target="_blank" rel="noopener"&gt;完全爆弾解除マニュアル:Keep Talking and Nobody Explodes&lt;/a&gt; を欲しがりました。
このゲームは、爆弾処理担当とマニュアル担当に分かれて協力するゲームで、マニュアル担当には紙のマニュアルが必要不可欠です（雰囲気を出すためにも）。&lt;/p&gt;
&lt;p&gt;せっかくなので、それらしく、かつコンパクトにする為に小冊子印刷 (ブックレット印刷) をすることにしました。&lt;/p&gt;
&lt;h2 id="試行錯誤の記録"&gt;試行錯誤の記録&lt;/h2&gt;
&lt;p&gt;「Ubuntu 小冊子」などで検索すると、いくつかの方法が見つかりましたが、簡単にはいきませんでした。&lt;/p&gt;
&lt;h3 id="標準のプリンタ設定"&gt;標準のプリンタ設定&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://help.ubuntu.com/stable/ubuntu-help/printing-booklet-duplex.html.ja" target="_blank" rel="noopener"&gt;公式ヘルプ&lt;/a&gt; には、「ページ番号を 4, 1, 2, 3 の順に入力して……」といった気の遠くなるような手動指定方法が記載されていました。ページ数が多いマニュアルでこれをやるのは現実的ではありません。&lt;/p&gt;
&lt;h3 id="既存ツール--失敗"&gt;既存ツール (失敗)&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href="https://github.com/coord-e/mkbookpdf" target="_blank" rel="noopener"&gt;mkbookpdf&lt;/a&gt;&lt;/strong&gt;&lt;/strong&gt;: Rust 製のツール。試してみましたが、以下のようなエラーで panic して動きませんでした。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;thread &amp;#39;main&amp;#39; panicked at library/core/src/panicking.rs:225:5:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;attempted to leave type `linked_hash_map::Node&amp;lt;alloc::vec::Vec&amp;lt;u8&amp;gt;, object::Object&amp;gt;` uninitialized, which is invalid
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href="https://www.boomaga.org/" target="_blank" rel="noopener"&gt;boomaga&lt;/a&gt;&lt;/strong&gt;&lt;/strong&gt;: 仮想プリンタツール。手順通り PPA を追加しようとしましたが、Ubuntu 24.04 (Noble) 向けのリリースが見つからず 404 エラーとなりました。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="解決策-pdfbook2"&gt;解決策: pdfbook2&lt;/h2&gt;
&lt;p&gt;最終的に動くことを確認出来たのは &lt;a href="https://github.com/jenom/pdfbook2" target="_blank" rel="noopener"&gt;pdfbook2&lt;/a&gt; でした。
これ自体は Python スクリプトですが、Ubuntu では &lt;code&gt;texlive-extra-utils&lt;/code&gt; パッケージの一部として提供されています。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt-cache search pdfbook2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;texlive-extra-utils - TeX Live: TeX auxiliary programs
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="インストール"&gt;インストール&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install texlive-extra-utils
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;TexLive 関連の依存パッケージが大量にインストールされるため、環境によっては時間がかかります（手元では 2 分弱でした）。
また、ディスク容量も消費します（手元の環境では &lt;code&gt;/usr/share/texlive&lt;/code&gt; 全体で約 2.8GB ありました）。ストレージ残量には十分注意してください。&lt;/p&gt;
&lt;h3 id="使い方"&gt;使い方&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pdfbook2 KeepTalkingAndNobodyExplodes-BombDefusalManual-v1-ja.pdf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これを実行すると、 &lt;code&gt;KeepTalkingAndNobodyExplodes-BombDefusalManual-v1-ja-book.pdf&lt;/code&gt; というファイルが生成されます。&lt;/p&gt;
&lt;p&gt;このファイルを PDF ビューワで開き、プリンタの設定で &lt;strong&gt;&lt;strong&gt;「両面印刷（長辺とじ: Long-edge binding）」&lt;/strong&gt;&lt;/strong&gt; を指定して印刷します( 参考 &lt;a href="https://zenn.dev/goahi/articles/4bbf0645d12c00" target="_blank" rel="noopener"&gt;LinuxでPDFファイルを冊子印刷する&lt;/a&gt; )。&lt;/p&gt;
&lt;h3 id="終わりに"&gt;終わりに&lt;/h3&gt;
&lt;p&gt;印刷されたプリントを折り畳んでホチキスで留め、黒いビニールテープで保護してやると、冒頭の画像のような仕上がりになります
( 実際の写真を元に生成しています )。&lt;/p&gt;
&lt;p&gt;若干字が小さいですが、コンパクトで場所もとらず、それらしい感じになりました。子どものテンションも少しだけ上がったかもしれません。&lt;/p&gt;
&lt;p&gt;ゲーム自体も楽しめるのでおすすめです。お試しあれ。&lt;/p&gt;</description></item><item><title>Elastic Common Schema と OpenTelemetry Semantic Convention を通して Structured Logging について学んだ</title><link>https://www.yewton.net/2025/01/08/structured-logging-ecs-otel-semconv/</link><pubDate>Wed, 08 Jan 2025 23:35:00 +0900</pubDate><guid>https://www.yewton.net/2025/01/08/structured-logging-ecs-otel-semconv/</guid><description>&lt;div class="ox-hugo-toc toc"&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div class="heading"&gt;&amp;#30446;&amp;#27425;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#%e8%83%8c%e6%99%af"&gt;背景&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#structured-logging-%e3%81%a8%e3%81%af"&gt;Structured logging とは&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#spring-boot-%e3%81%a7%e3%81%ae-elastic-common-schema-%e5%88%a9%e7%94%a8"&gt;Spring Boot での Elastic Common Schema 利用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#spring-boot-%e3%81%a7%e3%81%ae-opentelemetry-%e5%88%a9%e7%94%a8"&gt;Spring Boot での OpenTelemetry 利用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e7%b5%82%e3%82%8f%e3%82%8a%e3%81%ab"&gt;終わりに&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;!--endtoc--&gt;
&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://spring.io/blog/2024/08/23/structured-logging-in-spring-boot-3-4" target="_blank" rel="noopener"&gt;Structured logging in Spring Boot 3.4&lt;/a&gt; で、 Structured logging のサポートが発表されていた。&lt;/p&gt;
&lt;p&gt;Spring Boot として提供される機能は分かったが、そもそもの Structured logging、構造化ロギングについて理解出来ていなかったので、調べることにした。&lt;/p&gt;
&lt;p&gt;とっかかりとして、 Spring Boot がサポートする Structured logging フォーマットとしていの一番に挙げられている &lt;a href="https://www.elastic.co/guide/en/ecs/8.11/ecs-reference.html" target="_blank" rel="noopener"&gt;Elastic Common Schema (ECS)&lt;/a&gt; を通して調べたことをまとめる。&lt;/p&gt;
&lt;h2 id="structured-logging-とは"&gt;Structured logging とは&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.elastic.co/guide/en/ecs/current/ecs-getting-started.html" target="_blank" rel="noopener"&gt;Getting Started | Elastic Common Schema (ECS) Reference [8.16] | Elastic&lt;/a&gt; には以下のようにある:&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;ECS enables and encourages users to normalize event data in order to better analyze, visualize, and correlate their events. Collected events can be normalized at ingest time, consistently searched across indices, and visualized predictably.&lt;/p&gt;
&lt;p&gt;Note that when adopting an Elastic solution, such as &lt;a href="https://www.elastic.co/observability" target="_blank" rel="noopener"&gt;Observability&lt;/a&gt; or &lt;a href="https://www.elastic.co/security" target="_blank" rel="noopener"&gt;Security&lt;/a&gt;, all events will map to ECS out of the box. Elastic provides an extensive set of &lt;a href="https://www.elastic.co/security" target="_blank" rel="noopener"&gt;integrations&lt;/a&gt; to simplify ingesting your data sources.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;特に後半は特定の Elastic ソリューションとの連携について語られているので、一見すると Spring Boot が Elastic 製品特化の機能をサポートしたかのように思えてしまうかもしれない。&lt;/p&gt;
&lt;p&gt;しかし、イベントデータの標準化によって Observability 等で一貫性の恩恵を得られるのは、何も Elastic 製品利用時に限ったことではないはず。&lt;/p&gt;
&lt;p&gt;Elastic スタックと共に語られる事の多い &lt;a href="https://grafana.com/" target="_blank" rel="noopener"&gt;Grafana&lt;/a&gt; の分散トレーシングソリューションである &lt;a href="https://grafana.com/docs/tempo/latest/traceql/trace-structure/" target="_blank" rel="noopener"&gt;Tempo のドキュメント&lt;/a&gt; には、vendor-agnositc な Observability フレームワークである &lt;a href="https://opentelemetry.io/" target="_blank" rel="noopener"&gt;OpenTelemetry&lt;/a&gt; が提供する &lt;a href="https://opentelemetry.io/docs/specs/semconv/" target="_blank" rel="noopener"&gt;OpenTelemetry Semantic Conventions 1.29.0 | OpenTelemetry&lt;/a&gt; について言及されている。&lt;/p&gt;
&lt;p&gt;OpenTelemetry Semantic Conventions に従うことの恩恵は以下のように述べられている:&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;The benefit to using Semantic Conventions is in following a common naming scheme that can be standardized across a codebase, libraries, and platforms. This allows easier correlation and consumption of data.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;異なるシステム間のデータでも共通の規約に従ってさえいれば、突合などし易いし便利だよね、というのは、 ECS と同様に見える。&lt;/p&gt;
&lt;p&gt;目指すものは同じということで、実際 &lt;strong&gt;ECS と OTel SemConv は統合していく&lt;/strong&gt; ことが発表されている。&lt;/p&gt;
&lt;h3 id="elastic-common-schema-と-opentelemetry-semantic-convention-の統合"&gt;Elastic Common Schema と OpenTelemetry Semantic Convention の統合&lt;/h3&gt;
&lt;p&gt;両者の関係は &lt;a href="https://github.com/open-telemetry/oteps/blob/main/text/0199-support-elastic-common-schema-in-opentelemetry.md#scope-and-overlap-of-ecs-and-otel-semconv" target="_blank" rel="noopener"&gt;oteps/text/0199-support-elastic-common-schema-in-opentelemetry.md at main · open-telemetry/oteps&lt;/a&gt; の図を見ると分かり易い。&lt;/p&gt;
&lt;p&gt;提供価値被ってるし、統合した方がよいよね、ということで Elastic と OpenTelemetry からそれぞれ以下のアナウンスがあった:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://opentelemetry.io/blog/2023/ecs-otel-semconv-convergence/" target="_blank" rel="noopener"&gt;Announcing the Elastic Common Schema (ECS) and OpenTelemetry Semantic Convention Convergence | OpenTelemetry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.elastic.co/blog/ecs-elastic-common-schema-otel-opentelemetry-announcement" target="_blank" rel="noopener"&gt;Elastic contributes Elastic Common Schema (ECS) to OpenTelemetry project, helping accelerate adoption of OTel-based observability and security | Elastic Blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以下のように、 ECS への追加は OTel SemConv からのバックポートとして行うようなことが案内されていたり、&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/elastic/ecs/blob/main/CONTRIBUTING.md#ecs-donation-to-opentelemetry" target="_blank" rel="noopener"&gt;https://github.com/elastic/ecs/blob/main/CONTRIBUTING.md#ecs-donation-to-opentelemetry&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://opentelemetry.io/community/roadmap/" target="_blank" rel="noopener"&gt;OpenTelemetry Project Roadmap | OpenTelemetry&lt;/a&gt; には Further Stabilizing Semantic Conventions が most important major initiatives として挙げられているので、統合に向けて確実に進んでいるようではあるが、現在のところは安定して利用出来る具体的な成果物はまだ無いようだ。&lt;/p&gt;
&lt;p&gt;どちらかがいつか使えなくなるような破壊的な統合というわけではなさそうなので、今のところはこの両者があり、相反するものではなくいずれ統合される予定、ということを認識しておくだけで問題無さそうである。&lt;/p&gt;
&lt;h2 id="spring-boot-での-elastic-common-schema-利用"&gt;Spring Boot での Elastic Common Schema 利用&lt;/h2&gt;
&lt;p&gt;先に挙げた &lt;a href="https://spring.io/blog/2024/08/23/structured-logging-in-spring-boot-3-4" target="_blank" rel="noopener"&gt;Structured logging in Spring Boot 3.4&lt;/a&gt; に拠れば、 &lt;code&gt;logging.structured.format.console=ecs&lt;/code&gt; と設定するだけで以下のようなログが出力されるようになる:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;@timestamp&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2024-07-30T08:41:10.561295200Z&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;log.level&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;INFO&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;process.pid&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;67455&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;process.thread.name&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;main&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;service.name&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;structured-logging-demo&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;log.logger&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;com.example.structured_logging_demo.StructuredLoggingDemoApplication&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;message&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Started StructuredLoggingDemoApplication in 0.329 seconds (process running for 0.486)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;ecs.version&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;8.11&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これらのフィールドは以下のように ECS で定義されている:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.elastic.co/guide/en/ecs/current/ecs-base.html#field-timestamp" target="_blank" rel="noopener"&gt;@timestamp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.elastic.co/guide/en/ecs/current/ecs-log.html#field-log-level" target="_blank" rel="noopener"&gt;log.level&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.elastic.co/guide/en/ecs/current/ecs-process.html#field-process-pid" target="_blank" rel="noopener"&gt;process.pid&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.elastic.co/guide/en/ecs/current/ecs-process.html#field-process-thread-name" target="_blank" rel="noopener"&gt;process.thread.name&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.elastic.co/guide/en/ecs/current/ecs-service.html#field-service-name" target="_blank" rel="noopener"&gt;service.name&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.elastic.co/guide/en/ecs/current/ecs-log.html#field-log-logger" target="_blank" rel="noopener"&gt;log.logger&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.elastic.co/guide/en/ecs/current/ecs-base.html#field-message" target="_blank" rel="noopener"&gt;message&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;実は Elastic 提供の &lt;a href="https://github.com/elastic/ecs-logging-java/tree/v1.6.0?tab=readme-ov-file" target="_blank" rel="noopener"&gt;elastic/ecs-logging-java at v1.6.0&lt;/a&gt; というものもあるのだが、 Spring Boot はこれを使っているわけ &lt;strong&gt;ではない&lt;/strong&gt; 。
&lt;a href="https://github.com/spring-projects/spring-boot/blob/v3.4.1/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/logback/ElasticCommonSchemaStructuredLogFormatter.java#L52-L72" target="_blank" rel="noopener"&gt;独自に実装している&lt;/a&gt; 。&lt;/p&gt;
&lt;p&gt;ecs-logging-java の方には &lt;code&gt;process.*&lt;/code&gt; のフィールドは含まれないなど、出力項目にも違いがある模様。&lt;/p&gt;
&lt;p&gt;ただし、いずれもフィールド名は ECS に則っている。&lt;/p&gt;
&lt;div class="callout flex px-4 py-3 mb-6 rounded-md border-l-4 bg-blue-100 dark:bg-blue-900 border-blue-500"
data-callout="note"
data-callout-metadata=""&gt;
&lt;span class="callout-icon pr-3 pt-1 text-blue-600 dark:text-blue-300"&gt;
&lt;svg height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&gt;&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="m16.862 4.487l1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8l.8-2.685a4.5 4.5 0 0 1 1.13-1.897zm0 0L19.5 7.125"/&gt;&lt;/svg&gt;
&lt;/span&gt;
&lt;div class="callout-content dark:text-neutral-300"&gt;
&lt;div class="callout-title font-semibold mb-1"&gt;Note&lt;/div&gt;
&lt;div class="callout-body"&gt;&lt;p&gt;ecs-logging-java の Logback 版には、以下の issue が報告されている:
&lt;a href="https://github.com/elastic/ecs-logging-java/issues/49" target="_blank" rel="noopener"&gt;Support structured logging with Logback · Issue #49 · elastic/ecs-logging-java&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;この対応は Spring Boot の実装版には入っているようす。&lt;/p&gt;
&lt;p&gt;他にも、依存している Logback のバージョンが ecs-logging-java は UNMAINTAINED な 1.2 系だったりもするので、
Spring Boot を使うならば、 ecs-logging-java ではなく、組込みの機能を使っておいた方がよさそうだ。&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="spring-boot-での-opentelemetry-利用"&gt;Spring Boot での OpenTelemetry 利用&lt;/h2&gt;
&lt;p&gt;ECS と OTel SemConv 統合作業は今まさに進行中という感じで、ログに関しても &lt;a href="https://github.com/open-telemetry/community#specification-sigs" target="_blank" rel="noopener"&gt;open-telemetry/community: OpenTelemetry community content&lt;/a&gt; から辿れる &lt;a href="https://docs.google.com/document/d/1BKjQWP32FXL9g1cGbyj7DMXV1Uq%5FRL8%5F78rWaMBhN0A/edit?tab=t.0" target="_blank" rel="noopener"&gt;OpenTelemetry Log SIG - Google ドキュメント&lt;/a&gt; にて、 &lt;a href="https://github.com/open-telemetry/semantic-conventions/issues/1651" target="_blank" rel="noopener"&gt;Logs/Events guidance on what to put to attributes vs body · Issue #1651 · open-telemetry/semantic-conventions&lt;/a&gt; が挙げられていた事からも、活発に議論がされているようす。&lt;/p&gt;
&lt;p&gt;いずれ ECS と OTel SemConv は同等になっていくと思われるので、目下は ECS を利用しておけば問題はなさそうだが、統合先となる OTel SemConv を今から使っていく、ということは出来るのだろうか。&lt;/p&gt;
&lt;p&gt;以下の議論を見る限り、 OTel SemConv への対応は消極的？&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/spring-projects/spring-boot/issues/34132" target="_blank" rel="noopener"&gt;Micrometer Tracing with OTEL Bridge does not honour Semantic Conventions · Issue #34132 · spring-projects/spring-boot&lt;/a&gt;
&lt;a href="https://github.com/micrometer-metrics/tracing/issues/929" target="_blank" rel="noopener"&gt;Implement OTel HTTP semantic conventions · Issue #929 · micrometer-metrics/tracing&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Java の artifact がまだ alpha 状態であることが理由だそう。
確かに、 stable な spec に対する artifact でも &lt;a href="https://search.maven.org/artifact/io.opentelemetry.semconv/opentelemetry-semconv/1.29.0-alpha/jar?eh" target="_blank" rel="noopener"&gt;1.29.0-alpha&lt;/a&gt; のようなバージョニングになっている。&lt;/p&gt;
&lt;p&gt;ただし、上記はメトリクスの命名規約の文脈なので、 ECS 対応のように独自実装で対応されることはあるのかもしれない。&lt;/p&gt;
&lt;p&gt;現状でも、 OpenTelemetry の Appender を利用することは可能。
&lt;a href="https://docs.spring.io/spring-boot/reference/actuator/loggers.html#actuator.loggers.opentelemetry" target="_blank" rel="noopener"&gt;https://docs.spring.io/spring-boot/reference/actuator/loggers.html#actuator.loggers.opentelemetry&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;これは &lt;a href="https://opentelemetry.io/docs/specs/otlp/" target="_blank" rel="noopener"&gt;OpenTelemetry Protocol (OTLP)&lt;/a&gt; に従って、 gRPC や HTTP などで &lt;a href="https://opentelemetry.io/docs/specs/otel/" target="_blank" rel="noopener"&gt;OpenTelemetry Specification&lt;/a&gt; に則ったデータを送信する機能で、 OTel SemConv のような標準規格というよりは OpenTelemetry という実装に特化した機能。&lt;/p&gt;
&lt;p&gt;これで利用される &lt;a href="https://opentelemetry.io/docs/specs/otel/logs/data-model/" target="_blank" rel="noopener"&gt;Logs Data Model&lt;/a&gt; は OTel SemConv に則って定義されていたりするので、無関係というわけではない。&lt;/p&gt;
&lt;p&gt;実際に先程のような Spring Boot 起動ログを OTLP で送信した内容を JSON で表現すると以下のようになる:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;body&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Started PetclinicApplicationKt in 4.534 seconds (process running for 4.958)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;severity&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;INFO&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;attributes&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;code.filepath&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;StartupInfoLogger.java&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;code.function&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;logStarted&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;code.lineno&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;59&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;code.namespace&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;org.springframework.boot.StartupInfoLogger&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;process.pid&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;388042&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;thread.name&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;restartedMain&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;resources&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;service.name&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;petclinic-fullstack&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;telemetry.sdk.language&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;java&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;telemetry.sdk.name&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;opentelemetry&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;telemetry.sdk.version&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;1.43.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;instrumentation_scope&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;net.yewton.petclinic.PetclinicApplicationKt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;構造が入れ子になっていたりするが、末端のフィールド名は OTel SemConv に準拠している。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://opentelemetry.io/docs/specs/semconv/attributes-registry/code/#code-filepath" target="_blank" rel="noopener"&gt;code.filepath&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://opentelemetry.io/docs/specs/semconv/attributes-registry/code/#code-function" target="_blank" rel="noopener"&gt;code.function&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://opentelemetry.io/docs/specs/semconv/attributes-registry/code/#code-lineno" target="_blank" rel="noopener"&gt;code.lineno&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://opentelemetry.io/docs/specs/semconv/attributes-registry/code/#code-namespace" target="_blank" rel="noopener"&gt;code.namespace&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://opentelemetry.io/docs/specs/semconv/attributes-registry/process/#process-pid" target="_blank" rel="noopener"&gt;process.pid&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://opentelemetry.io/docs/specs/semconv/attributes-registry/thread/#thread-name" target="_blank" rel="noopener"&gt;thread.name&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://opentelemetry.io/docs/specs/semconv/attributes-registry/service/#service-name" target="_blank" rel="noopener"&gt;service.name&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://opentelemetry.io/docs/specs/semconv/attributes-registry/telemetry/#telemetry-sdk-language" target="_blank" rel="noopener"&gt;telemetry.sdk.language&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://opentelemetry.io/docs/specs/semconv/attributes-registry/telemetry/#telemetry-sdk-name" target="_blank" rel="noopener"&gt;telemetry.sdk.name&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://opentelemetry.io/docs/specs/semconv/attributes-registry/telemetry/#telemetry-sdk-version" target="_blank" rel="noopener"&gt;telemetry.sdk.version&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://github.com/yewton/petclinic/tree/otlp" target="_blank" rel="noopener"&gt;https://github.com/yewton/petclinic/tree/otlp&lt;/a&gt; に確認に利用したプロジェクトがある。&lt;/p&gt;
&lt;div class="callout flex px-4 py-3 mb-6 rounded-md border-l-4 bg-blue-100 dark:bg-blue-900 border-blue-500"
data-callout="note"
data-callout-metadata=""&gt;
&lt;span class="callout-icon pr-3 pt-1 text-blue-600 dark:text-blue-300"&gt;
&lt;svg height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&gt;&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="m16.862 4.487l1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8l.8-2.685a4.5 4.5 0 0 1 1.13-1.897zm0 0L19.5 7.125"/&gt;&lt;/svg&gt;
&lt;/span&gt;
&lt;div class="callout-content dark:text-neutral-300"&gt;
&lt;div class="callout-title font-semibold mb-1"&gt;Note&lt;/div&gt;
&lt;div class="callout-body"&gt;&lt;p&gt;以下で述べられているように、このように適切に構造化してデータ連携する場合は OTLP で直接送信するのがお手軽だが、
この方式はアプリケーションプロセスから通信処理をする為、オーバーヘッドがある。&lt;/p&gt;
&lt;p&gt;ファイルや標準出力に吐いたログを別プロセスで収集する方が当然パフォーマンスメリットはあるが、その為に
いい感じに構造化・シリアライズしてログ出力し、それを OTLP で送信するような機構は提供されていない。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://opentelemetry.io/docs/languages/java/instrumentation/#log-instrumentation" target="_blank" rel="noopener"&gt;https://opentelemetry.io/docs/languages/java/instrumentation/#log-instrumentation&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;実際には Fluent Bit などのログ収集ソリューションと併用することになりそう。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://docs.fluentbit.io/manual/pipeline/outputs/opentelemetry" target="_blank" rel="noopener"&gt;https://docs.fluentbit.io/manual/pipeline/outputs/opentelemetry&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="callout flex px-4 py-3 mb-6 rounded-md border-l-4 bg-blue-100 dark:bg-blue-900 border-blue-500"
data-callout="note"
data-callout-metadata=""&gt;
&lt;span class="callout-icon pr-3 pt-1 text-blue-600 dark:text-blue-300"&gt;
&lt;svg height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&gt;&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="m16.862 4.487l1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8l.8-2.685a4.5 4.5 0 0 1 1.13-1.897zm0 0L19.5 7.125"/&gt;&lt;/svg&gt;
&lt;/span&gt;
&lt;div class="callout-content dark:text-neutral-300"&gt;
&lt;div class="callout-title font-semibold mb-1"&gt;Note&lt;/div&gt;
&lt;div class="callout-body"&gt;&lt;p&gt;2025年1月8日現在は、 appender 群も alpha バージョンであることにも注意。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://central.sonatype.com/artifact/io.opentelemetry.instrumentation/opentelemetry-logback-appender-1.0/versios" target="_blank" rel="noopener"&gt;https://central.sonatype.com/artifact/io.opentelemetry.instrumentation/opentelemetry-logback-appender-1.0/versios&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://central.sonatype.com/artifact/io.opentelemetry.instrumentation/opentelemetry-log4j-appender-2.17/versions" target="_blank" rel="noopener"&gt;https://central.sonatype.com/artifact/io.opentelemetry.instrumentation/opentelemetry-log4j-appender-2.17/versions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;参考までに、上記の JSON は OTLP で収集したデータを加工したもので、実際は以下のようなデータが送信されている:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ResourceLog #0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Resource SchemaURL:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Resource attributes:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; service.name: Str(petclinic-fullstack)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; telemetry.sdk.language: Str(java)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; telemetry.sdk.name: Str(opentelemetry)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; telemetry.sdk.version: Str(1.43.0)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ScopeLogs #3
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ScopeLogs SchemaURL:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;InstrumentationScope net.yewton.petclinic.PetclinicApplicationKt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;LogRecord #0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ObservedTimestamp: 2025-01-04 13:41:59.821289163 +0000 UTC
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Timestamp: 2025-01-04 13:41:59.820892799 +0000 UTC
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;SeverityText: INFO
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;SeverityNumber: Info(9)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Body: Str(Started PetclinicApplicationKt in 4.534 seconds (process running for 4.958))
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Attributes:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; code.filepath: Str(StartupInfoLogger.java)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; code.function: Str(logStarted)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; code.lineno: Int(59)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; code.namespace: Str(org.springframework.boot.StartupInfoLogger)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; process.pid: Str(388042)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; thread.name: Str(restartedMain)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Trace ID:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Span ID:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Flags: 0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="終わりに"&gt;終わりに&lt;/h2&gt;
&lt;p&gt;ECS や OTel SemConv といった標準的なスキーマが定まっていく動きはとてもありがたい。&lt;/p&gt;
&lt;p&gt;長期的には OTel SemConv がデファクトスタンダードになっていきそうな勢いではあるが、
現在の状況はかなり流動的な為、実装としては Spring Boot でもサポートされる ECS を採用しておけば問題なさそう。&lt;/p&gt;
&lt;p&gt;規約に則ってさえいれば、可観測性やセキュリティといった非機能要件はこうしておけば OK!
…というような知見が今後貯まっていくはずなので期待。&lt;/p&gt;</description></item><item><title>Dell Latitude 3420 の SSD をより大容量の SSD に Clonezilla でクローンし換装する</title><link>https://www.yewton.net/2025/01/06/dell-latitude-3420-storage/</link><pubDate>Mon, 06 Jan 2025 01:05:00 +0900</pubDate><guid>https://www.yewton.net/2025/01/06/dell-latitude-3420-storage/</guid><description>&lt;div class="ox-hugo-toc toc"&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div class="heading"&gt;&amp;#30446;&amp;#27425;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#%e3%81%af%e3%81%98%e3%82%81%e3%81%ab"&gt;はじめに&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#clonezilla-%e3%81%ab%e3%82%88%e3%82%8b-ssd-%e3%82%af%e3%83%ad%e3%83%bc%e3%83%b3"&gt;Clonezilla による SSD クローン&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#ssd-%e3%81%ae%e6%8f%9b%e8%a3%85"&gt;SSD の換装&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e3%83%a1%e3%83%a2%e3%83%aa%e3%81%ae%e6%8f%9b%e8%a3%85"&gt;メモリの換装&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e5%8b%95%e4%bd%9c%e7%a2%ba%e8%aa%8d"&gt;動作確認&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;!--endtoc--&gt;
&lt;h2 id="はじめに"&gt;はじめに&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.yewton.net/2022/02/19/dell-latitude-3420-memory/"&gt;以前の記事&lt;/a&gt; では &lt;a href="https://japancatalog.dell.com/pd/latitude-3420.html" target="_blank" rel="noopener"&gt;Dell Latitude 3420&lt;/a&gt; にメモリを増設したが、今回は SSD を換装した。&lt;/p&gt;
&lt;p&gt;Docker イメージやら IDE やら何やらで 256 GiB でも心許なくなってきた為、 1 TiB の SSD に換装した。&lt;/p&gt;
&lt;p&gt;せっかくなので、ついでにメモリも追加で購入し、 8 GiB + 16 GiB の 24 GiB から 16 GiB × 2 で 32 GiB に。&lt;/p&gt;
&lt;p&gt;今回購入した SSD は、 &lt;a href="https://amzn.to/3DHMFZP" target="_blank" rel="noopener"&gt;キオクシア ( KIOXIA ) の EXCERIA PRO NVMe™ M.2 Type 2280-S2-M SSD 1TB&lt;/a&gt; 。
&lt;a href="https://www.dell.com/support/kbdoc/en-us/000185381/dell-latitude-3420-notebook-teardown-removal-guide-for-customer-replaceable-units-crus?lwp=rt" target="_blank" rel="noopener"&gt;Dell Latitude 3420 Notebook Teardown removal guide for customer replaceable units (CRUS) | Dell US&lt;/a&gt; に
M.2 SSD 2280 card slot の記載があるので問題ないハズ。&lt;/p&gt;
&lt;p&gt;この SSD を &lt;a href="https://amzn.to/40jZ5jc" target="_blank" rel="noopener"&gt;ロジテック ( Logitec ) の SSD ケース LGB-PNV02UC&lt;/a&gt; にセットして、データのクローンを行った。&lt;/p&gt;
&lt;p&gt;メモリは &lt;a href="https://amzn.to/405kHhX" target="_blank" rel="noopener"&gt;Crucial 16GB DDR4-3200 SODIMM D4N3200CM-16GQ&lt;/a&gt; を購入。&lt;/p&gt;
&lt;h2 id="clonezilla-による-ssd-クローン"&gt;Clonezilla による SSD クローン&lt;/h2&gt;
&lt;p&gt;クローンには &lt;a href="https://clonezilla.org/" target="_blank" rel="noopener"&gt;Clonezilla&lt;/a&gt; を利用した。&lt;/p&gt;
&lt;p&gt;まずは &lt;a href="https://clonezilla.org///liveusb.php" target="_blank" rel="noopener"&gt;Clonezilla Live on USB&lt;/a&gt; に従って Live USB を作成する。&lt;/p&gt;
&lt;p&gt;今回はたまたま余っていた &lt;a href="https://amzn.to/3PJ2Fh3" target="_blank" rel="noopener"&gt;エレコム 外付けポータブルSSD ESD-ED0120GBK 120GB&lt;/a&gt; を利用したが、 500 MiB あれば何でもよいハズ。&lt;/p&gt;
&lt;p&gt;手順に従い、 FAT でフォーマットした後に &lt;code&gt;unzip&lt;/code&gt; で配置して完成。&lt;/p&gt;
&lt;p&gt;この Live USB と、クローン先の SSD を収めたケースを接続した上で、 &lt;a href="https://www.dell.com/support/manuals/ja-jp/latitude-14-3420-laptop/latitude%5F3420%5Fcyborg%5Fsm/%E3%83%96%E3%83%BC%E3%83%88%E3%83%A1%E3%83%8B%E3%83%A5%E3%83%BC?guid=guid-493feb0b-5f68-470b-83ef-b8a975eb6e9d&amp;amp;lang=ja-jp#:~:text=%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%81%AE%E6%9C%89%E5%8A%B9%E3%81%AA%E8%B5%B7%E5%8B%95,%E3%82%92%E6%8A%BC%E3%81%97%E3%81%BE%E3%81%99%E3%80%82" target="_blank" rel="noopener"&gt;Latitude 3420 サービス マニュアル | Dell 日本&lt;/a&gt; に従い、起動後 Dell のロゴが表示されたときに &lt;code&gt;&amp;lt;F12&amp;gt;&lt;/code&gt; を押してブートメニューに入り、 Clonezilla の Live USB を選択する。&lt;/p&gt;
&lt;p&gt;その後は &lt;a href="https://clonezilla.org///fine-print-live-doc.php?path=clonezilla-live/doc/03%5FDisk%5Fto%5Fdisk%5Fclone" target="_blank" rel="noopener"&gt;Clonezilla Live Doc の Disk to disk clone のページ&lt;/a&gt; に従っていけばよい。&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2025/01/06/dell-latitude-3420-storage/2025-01-05_23-51-16_screenshot.png"
alt="図1: Start Clonezilla を選択する"&gt;&lt;figcaption&gt;
&lt;p&gt;図1: Start Clonezilla を選択する&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2025/01/06/dell-latitude-3420-storage/2025-01-05_23-52-43_screenshot.png"
alt="図2: device-device を選択する"&gt;&lt;figcaption&gt;
&lt;p&gt;図2: device-device を選択する&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;元々単一のパーティションにしていたので、今回は &lt;a href="https://clonezilla.org/clonezilla-live/doc/03%5FDisk%5Fto%5Fdisk%5Fclone/advanced/05-advanced-param.php" target="_blank" rel="noopener"&gt;Clonezilla - Advanced Mode&lt;/a&gt; に従いパーティションも含めてよしなに拡張するオプションを有効化する為、 &lt;code&gt;Expert&lt;/code&gt; を選択する。&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2025/01/06/dell-latitude-3420-storage/2025-01-05_23-57-51_screenshot.png"
alt="図3: Expert を選択する"&gt;&lt;figcaption&gt;
&lt;p&gt;図3: Expert を選択する&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2025/01/06/dell-latitude-3420-storage/2025-01-05_23-58-30_screenshot.png"
alt="図4: disk_to_local_disk を選択する"&gt;&lt;figcaption&gt;
&lt;p&gt;図4: disk_to_local_disk を選択する&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2025/01/06/dell-latitude-3420-storage/2025-01-06_00-04-16_screenshot.png"
alt="図5: クローン元のディスクを選択する"&gt;&lt;figcaption&gt;
&lt;p&gt;図5: クローン元のディスクを選択する&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2025/01/06/dell-latitude-3420-storage/2025-01-06_00-10-00_screenshot.png"
alt="図6: クローン先のディスクを選択する(元のデータは全消去される)"&gt;&lt;figcaption&gt;
&lt;p&gt;図6: クローン先のディスクを選択する(元のデータは全消去される)&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2025/01/06/dell-latitude-3420-storage/2025-01-06_00-11-37_screenshot.png"
alt="図7: advanced extra parameters はデフォルトのまま"&gt;&lt;figcaption&gt;
&lt;p&gt;図7: advanced extra parameters はデフォルトのまま&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2025/01/06/dell-latitude-3420-storage/2025-01-06_00-12-26_screenshot.png"
alt="図8: ファイルシステムのチェックはスキップ(デフォルト)"&gt;&lt;figcaption&gt;
&lt;p&gt;図8: ファイルシステムのチェックはスキップ(デフォルト)&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2025/01/06/dell-latitude-3420-storage/2025-01-06_00-13-22_screenshot.png"
alt="図9: ここで -k1 Create partition table proportionally を選択する"&gt;&lt;figcaption&gt;
&lt;p&gt;図9: ここで -k1 Create partition table proportionally を選択する&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2025/01/06/dell-latitude-3420-storage/2025-01-06_00-14-18_screenshot.png"
alt="図10: 終了後の挙動はその時に選択することにして、進める"&gt;&lt;figcaption&gt;
&lt;p&gt;図10: 終了後の挙動はその時に選択することにして、進める&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2025/01/06/dell-latitude-3420-storage/2025-01-06_00-15-15_screenshot.png"
alt="図11: とても熱心に確認してくれるので、覚悟を決めて y する"&gt;&lt;figcaption&gt;
&lt;p&gt;図11: とても熱心に確認してくれるので、覚悟を決めて y する&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;10 分程で完了するので、ここで電源オフ。&lt;/p&gt;
&lt;p&gt;続けて、クローンした SSD に換装する。&lt;/p&gt;
&lt;h2 id="ssd-の換装"&gt;SSD の換装&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.yewton.net/2022/02/19/dell-latitude-3420-memory/"&gt;以前の記事&lt;/a&gt; 同様にサービスモードに入り、ベースカバーを外して作業していく
( 今回気づいた点は以前の記事側に注記を入れた )。&lt;/p&gt;
&lt;p&gt;元々は M.2 type2242 が使われていた為、以下の部分でネジ止めされていた。&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2025/01/06/dell-latitude-3420-storage/2025-01-06_00-32-06_screenshot.png"
alt="図12: 元々ネジ止めされていた部分"&gt;&lt;figcaption&gt;
&lt;p&gt;図12: 元々ネジ止めされていた部分&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;換装するのは M.2 type2280 の為、この部品自体を移動する必要があった。&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2025/01/06/dell-latitude-3420-storage/2025-01-06_00-36-59_screenshot.png"
alt="図13: ネジを外して固定金具自体を移動する"&gt;&lt;figcaption&gt;
&lt;p&gt;図13: ネジを外して固定金具自体を移動する&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;この後、 SSD を接続して金具に固定し、 SSD の換装は完了。&lt;/p&gt;
&lt;h2 id="メモリの換装"&gt;メモリの換装&lt;/h2&gt;
&lt;p&gt;ついでの作業だが記録として。&lt;/p&gt;
&lt;p&gt;取り付けは &lt;a href="https://www.yewton.net/2022/02/19/dell-latitude-3420-memory/"&gt;以前の記事&lt;/a&gt; 同様だが、今回は元々入っていた 8 GiB メモリと交換する必要がある為、まず取り外す必要がある。&lt;/p&gt;
&lt;p&gt;以下の固定金具部分を外側に押し広げるような感じにすると、バインッと外れた。&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2025/01/06/dell-latitude-3420-storage/2025-01-06_00-42-26_screenshot.png"
alt="図14: 固定金具。右側は隠れてしまっているが同じ箇所にある。"&gt;&lt;figcaption&gt;
&lt;p&gt;図14: 固定金具。右側は隠れてしまっているが同じ箇所にある。&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;外したあとは、 &lt;a href="https://www.yewton.net/2022/02/19/dell-latitude-3420-memory/"&gt;以前の記事&lt;/a&gt; 同様に新しいメモリをセットして完了。&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2025/01/06/dell-latitude-3420-storage/2025-01-06_00-50-01_screenshot.png"
alt="図15: 追加分。こちら側は向きを逆にする必要があった。"&gt;&lt;figcaption&gt;
&lt;p&gt;図15: 追加分。こちら側は向きを逆にする必要があった。&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="動作確認"&gt;動作確認&lt;/h2&gt;
&lt;p&gt;SSD、メモリのセットが完了したので、ベースカバーを閉じて通電、起動を確認する。&lt;/p&gt;
&lt;p&gt;今回は以前と異なり、電源投入後に数分間無反応でヒヤヒヤしたが、その後問題無く起動し、追加のストレージ・RAM も問題無く認識された 🎉&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2025/01/06/dell-latitude-3420-storage/2025-01-06_01-02-47_screenshot.png"
alt="図16: Memory: 31.10 GiB 、 Disk (/): 907.06 GiB となっている"&gt;&lt;figcaption&gt;
&lt;p&gt;図16: Memory: 31.10 GiB 、 Disk (/): 907.06 GiB となっている&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;</description></item><item><title>Rust で GBA 開発のとっかかり</title><link>https://www.yewton.net/2024/05/12/gba-dev-rust/</link><pubDate>Sun, 12 May 2024 00:02:00 +0900</pubDate><guid>https://www.yewton.net/2024/05/12/gba-dev-rust/</guid><description>&lt;div class="ox-hugo-toc toc"&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div class="heading"&gt;&amp;#30446;&amp;#27425;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#%e8%83%8c%e6%99%af"&gt;背景&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#gba-%e9%96%8b%e7%99%ba%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6"&gt;GBA 開発について&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#agb-%e3%81%a7%e3%81%ae%e9%96%8b%e7%99%ba"&gt;agb での開発&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e6%88%90%e6%9e%9c%e7%89%a9"&gt;成果物&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e7%b5%82%e3%82%8f%e3%82%8a%e3%81%ab"&gt;終わりに&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;!--endtoc--&gt;
&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;p&gt;新しい言語を学ぶキッカケとして、 2015 年頃にほんの少しだけ触っていた GameBoy Advance の開発を
&lt;a href="https://www.rust-lang.org/" target="_blank" rel="noopener"&gt;Rust&lt;/a&gt; で出来ないかと検討していた。&lt;/p&gt;
&lt;p&gt;当時 &lt;a href="https://github.com/devkitPro/libgba" target="_blank" rel="noopener"&gt;libgba&lt;/a&gt; を利用してつくったものは以下。これらを Rust で書き直すことが目標。&lt;/p&gt;
&lt;h3 id="jumpingdroid"&gt;jumpingdroid&lt;/h3&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2024/05/12/gba-dev-rust/2024-05-11_20-44-18_jumpingdroid_mb-1.png"
alt="図1: ドロイド君が跳ねたり銀の林檎に乗ったりする"&gt;&lt;figcaption&gt;
&lt;p&gt;図1: ドロイド君が跳ねたり銀の林檎に乗ったりする&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;単純な背景と、複数スプライトの配置を試してみたもの。&lt;/p&gt;
&lt;p&gt;キャラクターを動かして何かに乗せる ( ように見せる ) 、というだけのことをやってみた。&lt;/p&gt;
&lt;h3 id="jumpingdroid2"&gt;jumpingdroid2&lt;/h3&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2024/05/12/gba-dev-rust/2024-05-11_20-57-33_jumpingdroid2_mb-1.png"
alt="図2: ドロイド君が右へ右へと進んでいく。ボタン押下で色も変わる。"&gt;&lt;figcaption&gt;
&lt;p&gt;図2: ドロイド君が右へ右へと進んでいく。ボタン押下で色も変わる。&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;1 画面に収まらないステージを横にスクロールしながら進んでいくだけのもの。&lt;/p&gt;
&lt;p&gt;画面外で次々に進行方向の背景を描画していくことで、キャラクターが進んでいるように見せる、ということをやってみた。&lt;/p&gt;
&lt;h2 id="gba-開発について"&gt;GBA 開発について&lt;/h2&gt;
&lt;p&gt;GBA の開発は普通のコンピュータ上で行なうようなものとは大分様相が異なる。&lt;/p&gt;
&lt;p&gt;OS なんてものはなく、「見渡す限りビットだらけ」である。&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;There is no operating system, no messing with drivers and hardware incompatibilities; it&amp;rsquo;s bits as far as the eye can see.&lt;/p&gt;
&lt;p&gt;&amp;ndash; &lt;a href="https://www.coranac.com/tonc/text/hardware.htm" target="_blank" rel="noopener"&gt;&lt;em&gt;Tonc: GBA Hardware&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;メモリの番地 &lt;code&gt;0x06000000&lt;/code&gt; からが背景画像のデータ領域で、 &lt;code&gt;0x06010000&lt;/code&gt; からはキャラクターのスプライト用のデータ、
個々のスプライトは &lt;code&gt;0x07000000&lt;/code&gt; から始まる領域で管理される、
というように、 &lt;strong&gt;ある特定のメモリ領域のビットを操作したらそれが画面に反映される&lt;/strong&gt; というのが基本的な仕組み。&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2024/05/12/gba-dev-rust/2024-05-11_21-43-09_screenshot.png"
alt="図3: ドロイド君の左下部分の画像が 0x06010040 にある様子"&gt;&lt;figcaption&gt;
&lt;p&gt;図3: ドロイド君の左下部分の画像が &lt;code&gt;0x06010040&lt;/code&gt; にある様子&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;jumpingdroid では BG (背景画像)とスプライトの基本的な機能を利用している。&lt;/p&gt;
&lt;h3 id="bg"&gt;BG&lt;/h3&gt;
&lt;p&gt;GBA では最大 4 枚の背景画像を利用でき、256×256 ピクセルや 256×512 ピクセルなどのサイズに設定出来る。&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2024/05/12/gba-dev-rust/2024-05-11_22-06-15_screenshot.png"
alt="図4: 256×256 ピクセルの BG"&gt;&lt;figcaption&gt;
&lt;p&gt;図4: 256×256 ピクセルの BG&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;GBA の画面は 240×160 ピクセルなので、上記の内実際に表示されるのは中央部分のみ。
スクロール表示の実現の為には、この非表示部分と表示オフセットを上手く利用することが必要になる。&lt;/p&gt;
&lt;h3 id="スプライト"&gt;スプライト&lt;/h3&gt;
&lt;p&gt;スプライトは小さな画像オブジェクトで、個別に移動させたり反転させたりといった操作が可能。
GBA では 8×8 から 64×64 ピクセルで、最大 128 個のスプライトを扱える。&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2024/05/12/gba-dev-rust/2024-05-11_22-15-29_screenshot.png"
alt="図5: 0x07000000 に格納されているドロイド君のスプライトデータ。参照先タイルは 0x06010180 にある。"&gt;&lt;figcaption&gt;
&lt;p&gt;図5: &lt;code&gt;0x07000000&lt;/code&gt; に格納されているドロイド君のスプライトデータ。参照先タイルは &lt;code&gt;0x06010180&lt;/code&gt; にある。&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id="高速紙芝居"&gt;高速紙芝居&lt;/h3&gt;
&lt;p&gt;無限ループの中で &lt;strong&gt;各ループ内で画面がどういう状態になるかをひたすら更新していく&lt;/strong&gt; 、というのが基本的なイメージ。&lt;/p&gt;
&lt;p&gt;各オブジェクトの状態とプレイヤーによるボタン入力の状態に応じて高速で画面を書き換えていくと動いているように見えるという、単純な仕組み。&lt;/p&gt;
&lt;p&gt;単純ゆえに、例えばただキャラクターを動かすといったことでも、全てゼロから定義する必要がある。&lt;/p&gt;
&lt;p&gt;移動や拡大・回転といった基本的な機能は提供されているが、それらをどう利用するかは完全に開発者次第。&lt;/p&gt;
&lt;h2 id="agb-での開発"&gt;agb での開発&lt;/h2&gt;
&lt;p&gt;今回利用する &lt;a href="https://agbrs.dev/" target="_blank" rel="noopener"&gt;agb&lt;/a&gt; というライブラリでは、 GBA でのゲーム開発に必要な機能をかなり抽象化して扱い易くしてくれている。&lt;/p&gt;
&lt;p&gt;スプライトは &lt;a href="https://www.aseprite.org/" target="_blank" rel="noopener"&gt;Aseprite&lt;/a&gt; というピクセルアート・アニメーション作成ツールのフォーマットをそのまま利用出来る
( Aseprite は購入するか、自身でビルドする必要がある )。&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2024/05/12/gba-dev-rust/2024-05-11_23-00-28_screenshot.png"
alt="図6: Aseprite の編集画面"&gt;&lt;figcaption&gt;
&lt;p&gt;図6: Aseprite の編集画面&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-rust" data-lang="rust"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;GRAPHICS&lt;/span&gt;: &lt;span class="kp"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nc"&gt;Graphics&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;agb&lt;/span&gt;::&lt;span class="fm"&gt;include_aseprite!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;gfx/sprites.aseprite&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;TAG_MAP&lt;/span&gt;: &lt;span class="kp"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nc"&gt;TagMap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;GRAPHICS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;IDLE&lt;/span&gt;: &lt;span class="kp"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nc"&gt;Tag&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;TAG_MAP&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Idle&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;WALKING&lt;/span&gt;: &lt;span class="kp"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nc"&gt;Tag&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;TAG_MAP&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Walking&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;JUMPING&lt;/span&gt;: &lt;span class="kp"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nc"&gt;Tag&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;TAG_MAP&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Jumping&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="src-block-caption"&gt;
&lt;span class="src-block-number"&gt;ソースコード 1&lt;/span&gt;:
コードからのスプライト用データ利用イメージ
&lt;/div&gt;
&lt;p&gt;BG データは png 等もそのまま扱える。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-rust" data-lang="rust"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;agb&lt;/span&gt;::&lt;span class="fm"&gt;include_background_gfx!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tiles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ff00ff&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 透過色
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;gfx/bg.png&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="src-block-caption"&gt;
&lt;span class="src-block-number"&gt;ソースコード 2&lt;/span&gt;:
コードからのBGデータ利用イメージ
&lt;/div&gt;
&lt;p&gt;これらはコンパイル時に GBA での利用に適した形に変換されているらしい。&lt;/p&gt;
&lt;p&gt;プログラム全体の構造をざっくり書くと以下のようになる:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-rust" data-lang="rust"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#[agb::entry]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;gba&lt;/span&gt;: &lt;span class="nc"&gt;agb&lt;/span&gt;::&lt;span class="n"&gt;Gba&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&amp;gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 初期化
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;gba&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_managed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;droid_object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;object_sprite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;IDLE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sprite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bg0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;gfx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;background&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Priority&lt;/span&gt;::&lt;span class="n"&gt;P0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;RegularBackgroundSize&lt;/span&gt;::&lt;span class="n"&gt;Background32x32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TileFormat&lt;/span&gt;::&lt;span class="n"&gt;FourBpp&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;loop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// フレーム毎に色々計算
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// BG のオフセット更新
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bg0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_scroll_pos&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;bg_offset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// BG のタイル状態更新
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bg0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_tile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vram&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bgx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bgy&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tileset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tiles&lt;/span&gt;::&lt;span class="n"&gt;bg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tile_settings&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tile_id&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bg0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vram&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;droid_object&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// スプライトの位置更新
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_position&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;dx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dy&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// スプライト画像更新
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_sprite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sprite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sprite_for_char&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;)));;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="src-block-caption"&gt;
&lt;span class="src-block-number"&gt;ソースコード 3&lt;/span&gt;:
agb を使った GBA プログラムの概要
&lt;/div&gt;
&lt;p&gt;実際のコードは以下:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/yewton/jumpingdroidr" target="_blank" rel="noopener"&gt;https://github.com/yewton/jumpingdroidr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/yewton/jumpingdroidr2" target="_blank" rel="noopener"&gt;https://github.com/yewton/jumpingdroidr2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="成果物"&gt;成果物&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://mgba.io/" target="_blank" rel="noopener"&gt;mGBA&lt;/a&gt; で jumpingdroidr2 を実行している様子が以下。&lt;/p&gt;
&lt;p&gt;BG1 のオフセットとタイルが更新される様子を併せて収録している。
ドロイド君の進行方向にステージを書き足していっている様子が観察出来る。&lt;/p&gt;
&lt;video controls &gt;
&lt;source src="https://www.yewton.net/2024/05/12/gba-dev-rust/Screencast%202024-05-11%2023:37:55.mp4" type="video/mp4"&gt;
&lt;/video&gt;
&lt;h2 id="終わりに"&gt;終わりに&lt;/h2&gt;
&lt;p&gt;普段の開発とは全く異なる考え方が必要になるため面白い。&lt;/p&gt;
&lt;p&gt;今回は GBA ソフトの移植を目的とした為に、Rust 自体の学習は必要最低限しかやらなかった。&lt;/p&gt;
&lt;p&gt;とっかかりは出来たので、今後細く長くやっていきたい。&lt;/p&gt;
&lt;p&gt;agb のリポジトリには例も豊富に提供されており、とても参考になる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://github.com/agbrs/agb/tree/master/agb/examples" target="_blank" rel="noopener"&gt;https://github.com/agbrs/agb/tree/master/agb/examples&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://github.com/agbrs/agb/tree/master/examples" target="_blank" rel="noopener"&gt;https://github.com/agbrs/agb/tree/master/examples&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;その他 GBA 開発関連の情報は &lt;a href="https://gbadev.net/" target="_blank" rel="noopener"&gt;Home | gbadev&lt;/a&gt; にまとまっている。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Org Mode でリンク種別に応じたプレフィクスを表示する</title><link>https://www.yewton.net/2023/04/01/org-link-prefix/</link><pubDate>Sat, 01 Apr 2023 22:47:00 +0900</pubDate><guid>https://www.yewton.net/2023/04/01/org-link-prefix/</guid><description>&lt;h2 id="tl-dr"&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/yewton/.emacs.d/blob/86b2642b1210f1c43489aa6b1e12d1c70856f8df/lisp/toncs-config-org.org#org-link" target="_blank" rel="noopener"&gt;https://github.com/yewton/.emacs.d/blob/86b2642b1210f1c43489aa6b1e12d1c70856f8df/lisp/toncs-config-org.org#org-link&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;上記のような設定で、上の画像のような表示になる。&lt;/p&gt;
&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;p&gt;org-roam で色々な情報を集約している時に、リンク先が org-mode のノートなのか、
それとも外部リンクなのか、等が &lt;code&gt;org-link-descriptive&lt;/code&gt; が有効な場合( デフォルト )に一見して分からない。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;org-toggle-link-display&lt;/code&gt; を使って一時的に全体を表示させたり、
&lt;a href="https://github.com/awth13/org-appear" target="_blank" rel="noopener"&gt;org-appear&lt;/a&gt; でカーソルを合わせた時に全体を表示させたり、
&lt;code&gt;help-at-pt-display-when-idle&lt;/code&gt; を有効にして、カーソルを合わせた時にエコーエリアにリンク先を表示させたり、
等々の一手間を掛ければ対処出来るが、その一手間が惜しかった。&lt;/p&gt;
&lt;h2 id="解決策"&gt;解決策&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;org-link-set-parameters&lt;/code&gt; を使い、 &lt;code&gt;org-link-parameters&lt;/code&gt; に登録されている全てのリンク種別 ( &lt;code&gt;org-link-types&lt;/code&gt; で取得する ) に対し、リンク種別を先頭にオーバーレイ表示する &lt;code&gt;:activate-func&lt;/code&gt; を登録する。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;:activate-func&lt;/code&gt; は、リンクがリンクとして判定され、有効になる際に実行される関数。
これを使うと、リンクの開始・終了位置を元にした任意の処理を実行出来る。&lt;/p&gt;
&lt;p&gt;この仕組みを使って、リンクの位置全体に対してオーバーレイを設定する。
&lt;code&gt;before-string&lt;/code&gt; オーバーレイプロパティに任意の文字列を設定すれば、簡単に prefix 表示が実現出来る。&lt;/p&gt;
&lt;p&gt;ただ、これだけでは若干問題があり、リンクの近辺で編集を行うと、その度に &lt;code&gt;:activate-fun&lt;/code&gt; が実行され、 &lt;strong&gt;何重にもオーバーレイが表示される&lt;/strong&gt; ことになってしまう。&lt;/p&gt;
&lt;p&gt;その為、 &lt;code&gt;:activate-fun&lt;/code&gt; 実行時に既存のオーバーレイを削除する必要がある。
適当なオーバーレイプロパティ ( &lt;code&gt;org-link-prefix&lt;/code&gt; 等 ) に値 &lt;code&gt;t&lt;/code&gt; を設定し、
オーバーレイ作成処理の前に &lt;code&gt;remove-overlays&lt;/code&gt; を実行、前述のプロパティを条件に削除を行うようにする。&lt;/p&gt;
&lt;p&gt;これで、リンク近辺の編集によってオーバーレイが無限増殖する自体は避けられるが、まだ問題がある。&lt;/p&gt;
&lt;p&gt;リンクの開始位置を変更するような編集 ( リンクの前にスペースを入力する等 ) を行うと、
&lt;strong&gt;元の位置に対して設定されたオーバーレイが消されず&lt;/strong&gt; ( 新しいリンク位置の範囲外になる為 )、
&lt;strong&gt;いつまでも残り続けてしまう&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;この対策には、 &lt;code&gt;insert-in-front-hooks&lt;/code&gt; オーバーレイプロパティを使う。
このプロパティには、オーバーレイの開始位置での編集に対して作用する関数群を登録出来る。
引数にはオーバーレイオブジェクトが渡される為、 &lt;code&gt;delete-overlay&lt;/code&gt; で削除すればよい。&lt;/p&gt;
&lt;p&gt;最後に、 &lt;code&gt;evaporate&lt;/code&gt; プロパティに &lt;code&gt;t&lt;/code&gt; を設定すれば、
オーバーレイ範囲が空になった際に自動で削除されるようになる。&lt;/p&gt;
&lt;p&gt;以上の設定により、リンク近辺の編集にも支障を来さずに、リンク種別のプレフィクスを表示することが出来る。&lt;/p&gt;
&lt;h2 id="おわりに"&gt;おわりに&lt;/h2&gt;
&lt;p&gt;リンクのプレフィクスとして設定する文字列は何でも良いが、
上部画像のように絵文字を設定しておくと見た目にも楽しくて良い。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/yewton/.emacs.d/blob/86b2642b1210f1c43489aa6b1e12d1c70856f8df/lisp/toncs-config.org#%E3%83%95%E3%82%A9%E3%83%B3%E3%83%88" target="_blank" rel="noopener"&gt;この設定&lt;/a&gt; 等を参考にすると、絵文字に対応したフォントセット設定が可能。&lt;/p&gt;</description></item><item><title>Spring Boot でプロファイルに応じて読み込む設定ファイルの設定値をテストする</title><link>https://www.yewton.net/2022/12/29/spring-boot-config-test/</link><pubDate>Thu, 29 Dec 2022 23:53:00 +0900</pubDate><guid>https://www.yewton.net/2022/12/29/spring-boot-config-test/</guid><description>&lt;h2 id="参考"&gt;参考&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.baeldung.com/spring-boot-testing-configurationproperties" target="_blank" rel="noopener"&gt;Testing Spring Boot @ConfigurationProperties | Baeldung&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nainaistar.hatenablog.com/entry/2021/03/30/120000" target="_blank" rel="noopener"&gt;【2021】SpringBootでpropertiesやymlの設定ファイルが読み込めることのテストを書く - きり丸の技術日記&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="本文"&gt;本文&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://docs.spring.io/spring-boot/docs/3.0.1/reference/htmlsingle/#features.external-config" target="_blank" rel="noopener"&gt;公式リファレンスドキュメント&lt;/a&gt; に記載されているように、 Spring Boot での外部設定ファイル読み込み方法は色々ある。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;application.(yml|properties)&lt;/code&gt; と、 &lt;a href="https://docs.spring.io/spring-boot/docs/3.0.1/reference/htmlsingle/#features.profiles" target="_blank" rel="noopener"&gt;Profile&lt;/a&gt; 毎に &lt;code&gt;application-production.(yml|properties)&lt;/code&gt; などを配置して &lt;a href="https://docs.spring.io/spring-boot/docs/3.0.1/reference/htmlsingle/#features.external-config.files.profile-specific" target="_blank" rel="noopener"&gt;プロファイル固有の設定を記述&lt;/a&gt; するのを基本として、
&lt;a href="https://docs.spring.io/spring-boot/docs/3.0.1/reference/htmlsingle/#features.external-config.files.importing" target="_blank" rel="noopener"&gt;&lt;code&gt;spring.config.import&lt;/code&gt;&lt;/a&gt; で追加の設定ファイルを読み込んだり、
&lt;a href="https://docs.spring.io/spring-boot/docs/3.0.1/reference/htmlsingle/#features.external-config.files.multi-document" target="_blank" rel="noopener"&gt;YAML のマルチドキュメント&lt;/a&gt; と &lt;code&gt;spring.config.activate.on-profile&lt;/code&gt; などを使って &lt;a href="https://docs.spring.io/spring-boot/docs/3.0.1/reference/htmlsingle/#features.external-config.files.activation-properties" target="_blank" rel="noopener"&gt;特定の条件で Property を有効化&lt;/a&gt; したり、
&lt;a href="https://docs.spring.io/spring-boot/docs/3.0.1/reference/htmlsingle/#features.profiles.groups" target="_blank" rel="noopener"&gt;Profile Groups&lt;/a&gt; でプロファイルをグループ化したり、等々。&lt;/p&gt;
&lt;p&gt;色々なやり方がある故に、例えば本番環境用など特定のプロファイルでベースの設定をオーバーライドしたい、というような場合に、ちょっと手の込んだ記述をしていたりすると、本当に意図した通りに値が設定されているか不安になることがある。&lt;/p&gt;
&lt;p&gt;実際にそのプロファイルで動かしてみるまで分からないのでは困るので、 test で確認出来るようにしてみる。&lt;/p&gt;
&lt;p&gt;実際のテストコードはこちら( &lt;a href="https://github.com/yewton/asobiba/blob/8af5b30f3c66669b1d83988713b98e6d32ef6aff/reactive-webapp/src/test/kotlin/net/yewton/asobiba/reactivewebapp/ProductionConfigTest.kt" target="_blank" rel="noopener"&gt;ProductionConfigTest.kt&lt;/a&gt; )。
&lt;a href="https://kotest.io/" target="_blank" rel="noopener"&gt;Kotest&lt;/a&gt; での記述になっているが、 Kotest 固有の部分は無い。&lt;/p&gt;
&lt;p&gt;全容は以下の通り。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-kotlin" data-lang="kotlin"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@ContextConfiguration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;initializers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ConfigDataApplicationContextInitializer&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@ActiveProfiles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;production&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProductionConfigTest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ConfigurableEnvironment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;FunSpec&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;R2DBC設定&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;spring.r2dbc.url&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldContain&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;prod.yewton.net:5432&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Redis設定&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;spring.data.redis.host&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldContain&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;prod.yewton.net&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-kotlin" data-lang="kotlin"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@ContextConfiguration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;initializers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ConfigDataApplicationContextInitializer&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://docs.spring.io/spring-framework/docs/6.0.3/javadoc-api/org/springframework/test/context/ContextConfiguration.html" target="_blank" rel="noopener"&gt;&lt;code&gt;@ContextConfiguration&lt;/code&gt;&lt;/a&gt; に &lt;a href="https://docs.spring.io/spring-boot/docs/3.0.1/api/org/springframework/boot/test/context/ConfigDataApplicationContextInitializer.html" target="_blank" rel="noopener"&gt;&lt;code&gt;org.springframework.boot.test.context.ConfigDataApplicationContextInitializer&lt;/code&gt;&lt;/a&gt; を指定することで、 &lt;code&gt;application.properties&lt;/code&gt; 等の設定ファイルをロードするよう指定出来るのは、冒頭の参考リンクにある通り。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-kotlin" data-lang="kotlin"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@ActiveProfiles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;production&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://docs.spring.io/spring-framework/docs/6.0.3/javadoc-api/org/springframework/test/context/ActiveProfiles.html" target="_blank" rel="noopener"&gt;@ActiveProfiles&lt;/a&gt; でテストしたいプロファイルを指定する。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-kotlin" data-lang="kotlin"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProductionConfigTest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ConfigurableEnvironment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;FunSpec&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;設定値は &lt;a href="https://docs.spring.io/spring-framework/docs/6.0.3/javadoc-api/org/springframework/core/env/ConfigurableEnvironment.html" target="_blank" rel="noopener"&gt;&lt;code&gt;ConfigurableEnvironment&lt;/code&gt;&lt;/a&gt; を autowire して取得する。&lt;/p&gt;
&lt;div class="callout flex px-4 py-3 mb-6 rounded-md border-l-4 bg-blue-100 dark:bg-blue-900 border-blue-500"
data-callout="note"
data-callout-metadata=""&gt;
&lt;span class="callout-icon pr-3 pt-1 text-blue-600 dark:text-blue-300"&gt;
&lt;svg height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&gt;&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="m16.862 4.487l1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8l.8-2.685a4.5 4.5 0 0 1 1.13-1.897zm0 0L19.5 7.125"/&gt;&lt;/svg&gt;
&lt;/span&gt;
&lt;div class="callout-content dark:text-neutral-300"&gt;
&lt;div class="callout-title font-semibold mb-1"&gt;Note&lt;/div&gt;
&lt;div class="callout-body"&gt;&lt;p&gt;&lt;code&gt;ConfigurableEnvironment&lt;/code&gt; は、 内部的に複数の &lt;a href="https://docs.spring.io/spring-framework/docs/6.0.3/javadoc-api/org/springframework/core/env/PropertySource.html" target="_blank" rel="noopener"&gt;&lt;code&gt;PropertySource&lt;/code&gt;&lt;/a&gt; を保持しており、これらを使ってプロパティの値を解決する。&lt;/p&gt;
&lt;p&gt;試しにデバッガで見てみると、読み込まれているファイル群を確認出来る:&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2022/12/29/spring-boot-config-test/2022-12-29_23-31-26_screenshot.png"&gt;
&lt;/figure&gt;
&lt;p&gt;ちなみに各 &lt;code&gt;PropertySource#source&lt;/code&gt; に、 &lt;code&gt;Map&lt;/code&gt; として設定値が格納されている:&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2022/12/29/spring-boot-config-test/2022-12-29_23-48-03_screenshot.png"&gt;
&lt;/figure&gt;
&lt;p&gt;これを利用して、設定キーの一覧を作成したりすることも可能。&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-kotlin" data-lang="kotlin"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;spring.r2dbc.url&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldContain&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;prod.yewton.net:5432&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="2022-12-29_23-31-26_screenshot.png"&gt;&lt;code&gt;PropertyResolver#getProperty&lt;/code&gt;&lt;/a&gt; メソッドで、特定のプロパティの値を取得出来る。&lt;/p&gt;
&lt;p&gt;この値を利用してどういったテストを書くかは、状況に応じて。&lt;/p&gt;</description></item><item><title>タスクランナー Task の紹介スライドを書いた</title><link>https://www.yewton.net/2022/11/24/task/</link><pubDate>Thu, 24 Nov 2022 22:04:00 +0900</pubDate><guid>https://www.yewton.net/2022/11/24/task/</guid><description>&lt;p&gt;&lt;a href="https://amzn.to/3TSpkqM" target="_blank" rel="noopener"&gt;Spring Microservices in Action, Second Edition&lt;/a&gt; の独習用に、 &lt;a href="https://github.com/yewton/my-smia" target="_blank" rel="noopener"&gt;https://github.com/yewton/my-smia&lt;/a&gt; というリポジトリで、実際に AWS に Terraform で環境構築してデプロイするところまでをやっている。&lt;/p&gt;
&lt;p&gt;その際に利用したタスクランナー &lt;a href="https://taskfile.dev/" target="_blank" rel="noopener"&gt;Task&lt;/a&gt; が、丁度いい感じに使えて良かった為、紹介するためのスライドを作った:&lt;/p&gt;
&lt;p&gt;
&lt;span class="inline-block pr-1"&gt;
&lt;span style="height: 1em; transform: translateY(0.1em);"&gt;external-link-alt&lt;/span&gt;
&lt;/span&gt; &lt;a href="https://yewton.github.io/my-marp-slides/2022-11%5Ftask/PITCHME.html" target="_blank" rel="noopener"&gt;タスクランナー Task の紹介&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;スライドにも書いたが、以下の点が特に気に入っている:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;環境変数の設定・切り替えが簡単&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pkg.go.dev/text/template" target="_blank" rel="noopener"&gt;Go Template&lt;/a&gt; が使える&lt;/li&gt;
&lt;li&gt;タスクの構造化が簡単・直感的&lt;/li&gt;
&lt;li&gt;無駄な実行を防ぐのが簡単&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/SchemaStore/schemastore/blob/master/src/schemas/json/taskfile.json" target="_blank" rel="noopener"&gt;JSON スキーマが公開されており&lt;/a&gt; 入力支援が効く&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;その他のツールとして YAML テンプレーティングツール &lt;a href="https://carvel.dev/ytt/docs/latest/" target="_blank" rel="noopener"&gt;ytt&lt;/a&gt; も便利だった。
こちらについてもその内紹介したい。&lt;/p&gt;</description></item><item><title>Ubuntu で Bluetooth マウスが使えない時にやるといいかもしれないこと</title><link>https://www.yewton.net/2022/05/29/ubuntu-bluetooth-troubleshoot/</link><pubDate>Sun, 29 May 2022 23:28:00 +0900</pubDate><guid>https://www.yewton.net/2022/05/29/ubuntu-bluetooth-troubleshoot/</guid><description>&lt;p&gt;&lt;a href="https://www.yewton.net/2021/10/11/dell-latitude-3420-byo-ubuntu/"&gt;以前購入した Dell Latitude 3420&lt;/a&gt; ( Xubuntu 入り )をクラムシェルで使うときに、マウスが入り用になった。&lt;/p&gt;
&lt;p&gt;元々 &lt;a href="https://amzn.to/3wZm0kh" target="_blank" rel="noopener"&gt;ロジクール M337&lt;/a&gt; を持っていたので、これを使えばいいと思っていたのだけれど、何故か検出されない。
具体的には &lt;code&gt;blueman-manager&lt;/code&gt; から、マウスが見えない。&lt;/p&gt;
&lt;p&gt;検索してみると &lt;a href="https://ubuntuforums.org/showthread.php?t=2390542" target="_blank" rel="noopener"&gt;[SOLVED] Bluetooth Mouse Won&amp;rsquo;t Connect after Reboot - Ubuntu 18.04 LTS&lt;/a&gt; が見つかった。&lt;/p&gt;
&lt;p&gt;理屈は分からないのだけれど、 &lt;a href="http://www.bluez.org/" target="_blank" rel="noopener"&gt;BlueZ&lt;/a&gt; の &lt;code&gt;bluetoothctl&lt;/code&gt; を使わないと接続出来ない機器があるらしい。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bluetoothctl
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;で、対話モードになる。この状態で&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;scan on
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;を実行すると、 &lt;code&gt;Bluetooth Mouse M336/M337/M535&lt;/code&gt; として検出された
( この時点で &lt;code&gt;blueman-manager&lt;/code&gt; の方でも表示されるようになっていた )。&lt;/p&gt;
&lt;p&gt;そして、デバイスの MAC アドレスを指定して、&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pair XX:XX:XX:XX:XX:XX
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;connect XX:XX:XX:XX:XX:XX
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;trust XX:XX:XX:XX:XX:XX
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;と実行すれば、ペアリングと接続が完了し、次回以降はマウス側から再接続も出来るようになった。&lt;/p&gt;</description></item><item><title>Dell Latitude 3420 にメモリを増設する</title><link>https://www.yewton.net/2022/02/19/dell-latitude-3420-memory/</link><pubDate>Sat, 19 Feb 2022 21:51:00 +0900</pubDate><guid>https://www.yewton.net/2022/02/19/dell-latitude-3420-memory/</guid><description>&lt;p&gt;&lt;a href="https://www.yewton.net/2021/10/11/dell-latitude-3420-byo-ubuntu/"&gt;以前の記事&lt;/a&gt; で書いた &lt;a href="https://japancatalog.dell.com/pd/latitude-3420.html" target="_blank" rel="noopener"&gt;Dell Latitude 3420&lt;/a&gt; だが、
普段使いに支障は無いものの、本格的に開発作業をしようと思うと
いささかメモリが心許ない( 8GiB )為、メモリを増設することにした。&lt;/p&gt;
&lt;p&gt;今回購入したのは、 &lt;a href="https://amzn.to/34T6Jr1" target="_blank" rel="noopener"&gt;Crucial 16GB DDR4-3200 SODIMM CT16G4SFRA32A&lt;/a&gt; 。
&lt;a href="https://www.crucial.jp/compatible-upgrade-for/dell/latitude-14-%283420%29" target="_blank" rel="noopener"&gt;Crucial のページ&lt;/a&gt; に Latitude 3420 との互換性が謳われていたのできっと安心。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.dell.com/support/kbdoc/ja-jp/000185381/" target="_blank" rel="noopener"&gt;Dell の公式ページ&lt;/a&gt; に、分解方法の解説がある為、これに従い分解していく。&lt;/p&gt;
&lt;p&gt;まずはサービスモードに入る必要がある。&lt;/p&gt;
&lt;p&gt;公式ページ記載の通りに、 &lt;code&gt;B&lt;/code&gt; キーを押しながら電源投入でいい…のだが、
ずっと押しっぱなしにしていると連打している扱いになるらしく、
確認画面などをすっ飛ばして直ぐ様
ビープ音を鳴らしつつサービスモードに入ってしまう。&lt;/p&gt;
&lt;p&gt;特に問題は無いと思うのだけれど、知らないとビックリするので注意。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;B&lt;/code&gt; を押しながら電源を入れ、3〜5 秒程度で離すと、
上手くいくと以下のように &lt;code&gt;OWNER TAG&lt;/code&gt; という文字列が表示される。&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2022/02/19/dell-latitude-3420-memory/2022-02-19_21-00-38_PXL_20220218_081810718.jpg"&gt;
&lt;/figure&gt;
&lt;div class="callout flex px-4 py-3 mb-6 rounded-md border-l-4 bg-blue-100 dark:bg-blue-900 border-blue-500"
data-callout="note"
data-callout-metadata=""&gt;
&lt;span class="callout-icon pr-3 pt-1 text-blue-600 dark:text-blue-300"&gt;
&lt;svg height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&gt;&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="m16.862 4.487l1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8l.8-2.685a4.5 4.5 0 0 1 1.13-1.897zm0 0L19.5 7.125"/&gt;&lt;/svg&gt;
&lt;/span&gt;
&lt;div class="callout-content dark:text-neutral-300"&gt;
&lt;div class="callout-title font-semibold mb-1"&gt;Note&lt;/div&gt;
&lt;div class="callout-body"&gt;&lt;p&gt;2025-01-06 追記: 次へ進むにはキーボードの任意のキーを押す必要がある。&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;更に AC アダプタの接続有無に関わらず、以下のような注意文言が表示され…&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;Please Remove AC Adapter&lt;/p&gt;
&lt;p&gt;Press Any Key To Continue&amp;hellip;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2022/02/19/dell-latitude-3420-memory/2022-02-19_21-02-53_PXL_20220218_081832378.jpg"&gt;
&lt;/figure&gt;
&lt;p&gt;最後に以下のような説明が出力され、
「カッカッ」とドキッとするようなビープ音が3回流れて電源が落ちる。&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;System Ready For Service After 3 Short Beeps (OR Wait 2 Seconds).&lt;/p&gt;
&lt;p&gt;After The Service Is Completed,
Plug In AC And Press And Hold The Power Button For 2 Seconds
To Resume Normal Operations.&lt;/p&gt;
&lt;p&gt;Press Any Key To Continue&amp;hellip;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2022/02/19/dell-latitude-3420-memory/2022-02-19_21-03-43_PXL_20220218_081846897.jpg"&gt;
&lt;/figure&gt;
&lt;p&gt;この後、公式ページ記載の通りに底面のベースカバーのネジを外す。&lt;/p&gt;
&lt;p&gt;そしてベースカバーを外せばいい…のだが、すんなりとはいかなかった。
どうやったら外せたのかよく分かっていないのだが、
おそらくヒンジ側中央部分の引っかかりをうまいこと外せれば、
あとは持ち上げるだけで外せる…ハズ。&lt;/p&gt;
&lt;div class="callout flex px-4 py-3 mb-6 rounded-md border-l-4 bg-blue-100 dark:bg-blue-900 border-blue-500"
data-callout="note"
data-callout-metadata=""&gt;
&lt;span class="callout-icon pr-3 pt-1 text-blue-600 dark:text-blue-300"&gt;
&lt;svg height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&gt;&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="m16.862 4.487l1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8l.8-2.685a4.5 4.5 0 0 1 1.13-1.897zm0 0L19.5 7.125"/&gt;&lt;/svg&gt;
&lt;/span&gt;
&lt;div class="callout-content dark:text-neutral-300"&gt;
&lt;div class="callout-title font-semibold mb-1"&gt;Note&lt;/div&gt;
&lt;div class="callout-body"&gt;&lt;p&gt;2025-01-06 追記: 左右のヒンジ部分を押し込むような感じに力を入れると外し易い。&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;上手く外せたら、以下の部分にメモリを差し込む。
元々 8GiB のが差さっているので、その反対側になる。&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2022/02/19/dell-latitude-3420-memory/2022-02-19_21-18-28_photo1.jpg"&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href="https://www.iodata.jp/product/memory/info/tips/#list2" target="_blank" rel="noopener"&gt;メモリーの増設方法 | IODATA アイ・オー・データ機器&lt;/a&gt; 等を参考に、
斜め 35 度くらいに差し込み、奥までいったら下に押し込む。&lt;/p&gt;
&lt;p&gt;カチッとハマッたら、再びベースカバーをネジ止めして、AC アダプタに接続する。&lt;/p&gt;
&lt;div class="callout flex px-4 py-3 mb-6 rounded-md border-l-4 bg-blue-100 dark:bg-blue-900 border-blue-500"
data-callout="note"
data-callout-metadata=""&gt;
&lt;span class="callout-icon pr-3 pt-1 text-blue-600 dark:text-blue-300"&gt;
&lt;svg height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&gt;&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="m16.862 4.487l1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8l.8-2.685a4.5 4.5 0 0 1 1.13-1.897zm0 0L19.5 7.125"/&gt;&lt;/svg&gt;
&lt;/span&gt;
&lt;div class="callout-content dark:text-neutral-300"&gt;
&lt;div class="callout-title font-semibold mb-1"&gt;Note&lt;/div&gt;
&lt;div class="callout-body"&gt;&lt;p&gt;2025-01-06 追記: ヒンジ側を先にしっかり嵌め込んでネジ止めし、その後に残りをネジ止めするとやり易い。&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;サービスモードに入るときの説明では、
AC アダプタ接続後に電源ボタンを押す的なことが書いてあったが、
自分の場合は接続後すぐに起動した。&lt;/p&gt;
&lt;p&gt;起動後は以下のような画面が表示される。&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;Alert! The amount of system memory has changed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2022/02/19/dell-latitude-3420-memory/2022-02-19_21-30-58_PXL_20220218_085238190.jpg"&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href="https://www.dell.com/support/kbdoc/ja-jp/000137726/" target="_blank" rel="noopener"&gt;Dell のサポート技術文書&lt;/a&gt; によれば、無視して構わないとのこと。&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;メモリを増設または取り外した場合、このメッセージは単なる通知として無視して構いません&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;以上で無事、既存の 8 GiB + 16 GiB で 24 GiB に RAM を増強出来た 🎉&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2022/02/19/dell-latitude-3420-memory/2022-02-19_21-41-36_screenshot.png"&gt;
&lt;/figure&gt;</description></item><item><title>consult-ripgrep と migemo を組み合わせて ripgrep でもローマ字日本語検索</title><link>https://www.yewton.net/2022/02/07/consult-ripgrep-migemo/</link><pubDate>Mon, 07 Feb 2022 23:29:00 +0900</pubDate><guid>https://www.yewton.net/2022/02/07/consult-ripgrep-migemo/</guid><description>&lt;p&gt;&lt;a href="https://www.yewton.net/2022/02/07/consult-ripgrep-migemo/"&gt;consult-ripgrep と migemo を組み合わせて ripgrep でもローマ字日本語検索&lt;/a&gt; の派生。&lt;/p&gt;
&lt;h2 id="tl-dr"&gt;TL;DR&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-emacs-lisp" data-lang="emacs-lisp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;;; -*- lexical-binding: t -*-&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;consult--migemo-regexp-compiler&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;input&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;input&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;mapcar&lt;/span&gt; &lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;migemo-get-pattern&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;consult--split-escaped&lt;/span&gt; &lt;span class="nv"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cons&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;mapcar&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;consult--convert-regexp&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="nv"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;when-let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;regexps&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;seq-filter&lt;/span&gt; &lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;consult--valid-regexp-p&lt;/span&gt; &lt;span class="nv"&gt;input&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;consult--highlight-regexps&lt;/span&gt; &lt;span class="nv"&gt;regexps&lt;/span&gt; &lt;span class="nv"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;migemo-options&lt;/span&gt; &lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;--quiet&amp;#34;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;--nonewline&amp;#34;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;--emacs&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;consult--regexp-compiler&lt;/span&gt; &lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;consult--migemo-regexp-compiler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="callout flex px-4 py-3 mb-6 rounded-md border-l-4 bg-orange-100 dark:bg-orange-900 border-orange-500"
data-callout="warning"
data-callout-metadata=""&gt;
&lt;span class="callout-icon pr-3 pt-1 text-orange-600 dark:text-orange-300"&gt;
&lt;svg height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&gt;&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0zM12 15.75h.007v.008H12z"/&gt;&lt;/svg&gt;
&lt;/span&gt;
&lt;div class="callout-content dark:text-neutral-300"&gt;
&lt;div class="callout-title font-semibold mb-1"&gt;Warning&lt;/div&gt;
&lt;div class="callout-body"&gt;&lt;p&gt;&lt;a href="https://www.gnu.org/software/emacs/manual/html%5Fnode/elisp/Lexical-Binding.html" target="_blank" rel="noopener"&gt;Lexical Binding&lt;/a&gt; が有効でないとエラーになります。&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="cosult-ripgrep-の仕組み"&gt;&lt;code&gt;cosult-ripgrep&lt;/code&gt; の仕組み&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;consult-ripgrep&lt;/code&gt; で指定する文字列は、 &lt;a href="https://github.com/minad/consult/blob/1a6ed29e92f00266daff4ff5f62602f53ef7d158/consult.el#L4311-L4318" target="_blank" rel="noopener"&gt;こちら&lt;/a&gt; にあるように構造化されている。&lt;/p&gt;
&lt;p&gt;特に &lt;code&gt;#first#second&lt;/code&gt; といった指定の場合に、
デフォルトでは区切り文字の前半(例の &lt;code&gt;first&lt;/code&gt; の部分)は基本的にそのまま &lt;code&gt;rg&lt;/code&gt; に渡され、
後半(例の &lt;code&gt;second&lt;/code&gt; の部分)は &lt;code&gt;rg&lt;/code&gt; の結果について更に Emacs 上で絞り込む、といった挙動になる
( 基本的に、と書いたのは Emacs の正規表現から &lt;code&gt;rg&lt;/code&gt; に渡せる正規表現に変換してくれるという
&lt;code&gt;counsel-rg&lt;/code&gt; と同じ似たような機構が備わっているから。&lt;a href="https://github.com/minad/consult/blob/1a6ed29e92f00266daff4ff5f62602f53ef7d158/consult.el#L571-L590" target="_blank" rel="noopener"&gt;この辺&lt;/a&gt; )。&lt;/p&gt;
&lt;p&gt;後者については &lt;a href="https://www.gnu.org/software/emacs/manual/html%5Fnode/emacs/Completion-Styles.html" target="_blank" rel="noopener"&gt;&lt;code&gt;completion-styles&lt;/code&gt;&lt;/a&gt; の指定通りの補完スタイルが適用される為、
&lt;a href="https://nyoho.jp/diary/?date=20210615" target="_blank" rel="noopener"&gt;consultをmigemoizeしたい (未完→だいたいできた) - ワタタツの日記!(2021-06-15)&lt;/a&gt; の記事にあるように
&lt;code&gt;completion-styles&lt;/code&gt; を設定していれば migemo が使用されるが、
前者については &lt;code&gt;consult-ripgrep&lt;/code&gt; 独自の仕組みなので &lt;code&gt;completion-styles&lt;/code&gt; には影響されない。&lt;/p&gt;
&lt;h2 id="consult-regexp-compiler"&gt;&lt;code&gt;consult--regexp-compiler&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/minad/consult/blob/1a6ed29e92f00266daff4ff5f62602f53ef7d158/consult.el#L4306-L4309" target="_blank" rel="noopener"&gt;consult-grep の DOCSTRING&lt;/a&gt; に以下の記載がある:&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;In order to disable transformations of the grep input, adjust `consult&amp;ndash;regexp-compiler&amp;rsquo; accordingly.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/minad/consult/blob/1a6ed29e92f00266daff4ff5f62602f53ef7d158/consult.el#L592-L602" target="_blank" rel="noopener"&gt;デフォルトの実装&lt;/a&gt; はこんな感じ:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-emacs-lisp" data-lang="emacs-lisp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;consult--default-regexp-compiler&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;input&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;Compile the INPUT string to a list of regular expressions.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;The function should return a pair, the list of regular expressions and a
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;highlight function. The highlight function should take a single argument, the
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;string to highlight given the INPUT. TYPE is the desired type of regular
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;expression, which can be &lt;/span&gt;&lt;span class="ss"&gt;`basic&amp;#39;&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="ss"&gt;`extended&amp;#39;&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="ss"&gt;`emacs&amp;#39;&lt;/span&gt;&lt;span class="s"&gt; or &lt;/span&gt;&lt;span class="ss"&gt;`pcre&amp;#39;&lt;/span&gt;&lt;span class="s"&gt;.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;input&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;consult--split-escaped&lt;/span&gt; &lt;span class="nv"&gt;input&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cons&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;mapcar&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;consult--convert-regexp&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="nv"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;when-let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;regexps&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;seq-filter&lt;/span&gt; &lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;consult--valid-regexp-p&lt;/span&gt; &lt;span class="nv"&gt;input&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;consult--highlight-regexps&lt;/span&gt; &lt;span class="nv"&gt;regexps&lt;/span&gt; &lt;span class="nv"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;入力文字列から最終的に &lt;code&gt;rg&lt;/code&gt; に渡される文字列を組み立てているここに、介入余地がある。&lt;/p&gt;
&lt;p&gt;ということで、冒頭のような設定を行い、 migemo 対応版の &lt;code&gt;consult--regexp-compiler&lt;/code&gt; を指定してやればよい。&lt;/p&gt;
&lt;div class="callout flex px-4 py-3 mb-6 rounded-md border-l-4 bg-orange-100 dark:bg-orange-900 border-orange-500"
data-callout="warning"
data-callout-metadata=""&gt;
&lt;span class="callout-icon pr-3 pt-1 text-orange-600 dark:text-orange-300"&gt;
&lt;svg height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&gt;&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0zM12 15.75h.007v.008H12z"/&gt;&lt;/svg&gt;
&lt;/span&gt;
&lt;div class="callout-content dark:text-neutral-300"&gt;
&lt;div class="callout-title font-semibold mb-1"&gt;Warning&lt;/div&gt;
&lt;div class="callout-body"&gt;&lt;p&gt;&lt;code&gt;consult--regexp-compiler&lt;/code&gt; はその命名からも分かる通り、あくまで内部変数のようである。
その為、今後の更新によって使えなくなる可能性も十分にある。&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Dell Latitude 3420 - Build Your Own で Ubuntu プリインストールなノート PC を楽しむ</title><link>https://www.yewton.net/2021/10/11/dell-latitude-3420-byo-ubuntu/</link><pubDate>Mon, 11 Oct 2021 23:44:00 +0900</pubDate><guid>https://www.yewton.net/2021/10/11/dell-latitude-3420-byo-ubuntu/</guid><description>
&lt;details class="print:hidden xl:hidden" &gt;
&lt;summary&gt;目次&lt;/summary&gt;
&lt;div class="text-sm"&gt;
&lt;nav id="TableOfContents"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#経緯"&gt;経緯&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#調達"&gt;調達&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#構成"&gt;構成&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#配送期間"&gt;配送期間&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#セットアップ"&gt;セットアップ&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#xubuntu-化"&gt;Xubuntu 化&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#指紋認証の設定"&gt;指紋認証の設定&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#その他のセットアップ"&gt;その他のセットアップ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#終わりに"&gt;終わりに&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/nav&gt;
&lt;/div&gt;
&lt;/details&gt;
&lt;h2 id="経緯"&gt;経緯&lt;/h2&gt;
&lt;p&gt;過去には、
&lt;a href="https://www.yewton.net/2020/02/13/macbookpro10-xubuntu/"&gt;MacBook Pro (Retina, 15-inch, Mid 2012) で macOS と Xubuntu 19.10 Eoan Ermine をデュアルブートする&lt;/a&gt; や、
&lt;a href="https://www.yewton.net/2020/06/18/jumper-ezbook2-xubuntu/"&gt;中古で12,800円の激安ノートPC(Jumper Ezbook 2)にXubuntu 20.04 LTS (Focal Fossa)を入れて幸せになる&lt;/a&gt; 、
&lt;a href="https://www.yewton.net/2021/02/21/acer-spin-311-emacs/"&gt;Chromebook Acer Spin 311 に Emacs を入れて幸せになる&lt;/a&gt; に於いて、
手元の型落ち品や安価な PC を調達しての Ubuntu ノート PC 化を行なってきたが、
それなりのスペックで、 GNU/Linux 搭載前提の PC を調達したい欲が高まっていた。&lt;/p&gt;
&lt;p&gt;そんな折、 Dell からなら Ubuntu プリインストールなノート PC を調達出来ることを
&lt;a href="https://ubuntu84.blogspot.com/2020/05/dellubuntu-2020531.html" target="_blank" rel="noopener"&gt;Linuxノートパソコンが買える DELL製9機種 2021/09/25更新 - 全部楽しもう&lt;/a&gt; で知ったので、
購入を決めた。&lt;/p&gt;
&lt;h2 id="調達"&gt;調達&lt;/h2&gt;
&lt;h3 id="構成"&gt;構成&lt;/h3&gt;
&lt;p&gt;今回購入したのは、14 インチの &lt;a href="https://japancatalog.dell.com/pd/latitude-3420.html" target="_blank" rel="noopener"&gt;Latitude 3420&lt;/a&gt; 。&lt;/p&gt;
&lt;p&gt;OS を &lt;strong&gt;Ubuntu Linux 20.04&lt;/strong&gt; にし、
CPU は &lt;strong&gt;Core i5-1135G7&lt;/strong&gt; に変更、メモリは &lt;strong&gt;8 GB (1 X 8 GB) 3200MHz DDR4 非-ECC&lt;/strong&gt; 、
電源ユニットを &lt;strong&gt;65W Type-C アダプター&lt;/strong&gt; に変更、
また、 &lt;strong&gt;電源ボタンを指紋リーダー付き&lt;/strong&gt; に、
キーボードを &lt;strong&gt;US 配列(バックライト付き)&lt;/strong&gt; にそれぞれ変更した。&lt;/p&gt;
&lt;p&gt;なお、バックライト付きキーボードは US 配列でないと選択出来ない。
US 配列使いでよかったと思う瞬間である。&lt;/p&gt;
&lt;p&gt;さらに奮発すると、 &lt;strong&gt;タッチディスプレイにも出来る&lt;/strong&gt; ようだったが、
今回はそこまではやらなかった。&lt;/p&gt;
&lt;p&gt;注文時点(2021年8月2日)では上記の構成で税抜き140,500円、クーポン適用で23,183円引きの119,426円となり、
最終的に &lt;strong&gt;税込131,368円&lt;/strong&gt; となった。&lt;/p&gt;
&lt;p&gt;特段、お安いワケではない。&lt;/p&gt;
&lt;p&gt;なお重量は &lt;strong&gt;1.52 kg 前後&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;MacBook Air(M1, 2020) が 1.29 kg、
13 インチ MacBook Pro(M1, 2020) が 1.4 kg、
16 インチ MacBook Pro が 2.0 kg ということなので、
いいセン行っているのではなかろうか。&lt;/p&gt;
&lt;h3 id="配送期間"&gt;配送期間&lt;/h3&gt;
&lt;p&gt;2021年8月2日に購入し、その時点では出荷予定日11月1日、到着予定が11月12日とあったが、
実際には9月8日に出荷され、9月22日に到着した。&lt;/p&gt;
&lt;p&gt;昨今の情勢影響もあろうが、 &lt;strong&gt;注文から到着まで 2ヶ月弱&lt;/strong&gt; かかっていたことになる。
元々の予定では3ヶ月以上待つことになっていたので、大分短縮されて有り難いことではある。&lt;/p&gt;
&lt;h2 id="セットアップ"&gt;セットアップ&lt;/h2&gt;
&lt;p&gt;今回のポイントは &lt;strong&gt;指紋認証を有効にする&lt;/strong&gt; 部分である。&lt;/p&gt;
&lt;p&gt;それ以外は普通に Ubuntu をセットアップをすればのだが、
いつもは最初から Xubuntu を入れていたところ、今回は &lt;strong&gt;後から Xubuntu 化&lt;/strong&gt; する、というのが異なる点。&lt;/p&gt;
&lt;h3 id="xubuntu-化"&gt;Xubuntu 化&lt;/h3&gt;
&lt;p&gt;まずは、パッケージを最新化:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt update -y &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo apt upgrade -y
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;次に、 Xubuntu を入れる。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install -y --auto-remove xubuntu-desktop xserver-xorg-input-synaptics- light-locker-
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Display manager は &lt;a href="https://github.com/canonical/lightdm" target="_blank" rel="noopener"&gt;lightdm&lt;/a&gt; を選択した。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://freedesktop.org/wiki/Software/libinput/" target="_blank" rel="noopener"&gt;libinput&lt;/a&gt; と競合して、ウインドウによってナチュラルスクロールが効かくなるといった弊害があるので、
&lt;a href="https://cgit.freedesktop.org/xorg/driver/xf86-input-synaptics/" target="_blank" rel="noopener"&gt;synaptics&lt;/a&gt; は最初から入れないようにする。&lt;/p&gt;
&lt;p&gt;また、 &lt;a href="https://docs.xfce.org/apps/screensaver/start" target="_blank" rel="noopener"&gt;xfce4-screensaver&lt;/a&gt; と &lt;a href="https://github.com/the-cavalry/light-locker" target="_blank" rel="noopener"&gt;light-locker&lt;/a&gt; も競合するので、light-locker の方を除外する。&lt;/p&gt;
&lt;p&gt;xfce4-screensaver のロック画面の方が、指紋認証後直ちにロック解除されるのに対し、
light-locker の方は認証後に Unlock ボタンを押下する必要がある(&lt;a href="https://github.com/Xubuntu/lightdm-gtk-greeter" target="_blank" rel="noopener"&gt;lightdm-gtk-greeter&lt;/a&gt; と同じ挙動)という、
細かい挙動の違いがある模様。&lt;/p&gt;
&lt;p&gt;続いて、タッチパッドのオプション設定を行う:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo mkdir /etc/X11/xorg.conf.d/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo tee /etc/X11/xorg.conf.d/30-touchpad.conf &lt;span class="s"&gt;&amp;lt;&amp;lt;EOF
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;Section &amp;#34;InputClass&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; Identifier &amp;#34;libinput touchpad catchall&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; MatchIsTouchpad &amp;#34;on&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; MatchDevicePath &amp;#34;/dev/input/event*&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; Driver &amp;#34;libinput&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; Option &amp;#34;Tapping&amp;#34; &amp;#34;on&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; Option &amp;#34;TappingDrag&amp;#34; &amp;#34;on&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; Option &amp;#34;TappingDragLock&amp;#34; &amp;#34;on&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; Option &amp;#34;NaturalScrolling&amp;#34; &amp;#34;on&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; Option &amp;#34;DisableWhileTyping&amp;#34; &amp;#34;on&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; Option &amp;#34;ClickMethod&amp;#34; &amp;#34;clickfinger&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EndSection
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;オプション詳細は &lt;a href="https://manned.org/libinput.4" target="_blank" rel="noopener"&gt;libinput の man(4)&lt;/a&gt; を参照。&lt;/p&gt;
&lt;p&gt;続いて、キーボード設定を行う:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo localectl --no-convert set-x11-keymap us pc105 &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt; ctrl:nocaps
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;オプション詳細は &lt;a href="https://manned.org/keyboard.5" target="_blank" rel="noopener"&gt;keyboard の man(5)&lt;/a&gt; を参照。&lt;/p&gt;
&lt;p&gt;ここまでで一旦再起動する。再起動後には Xubuntu 化されている。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo reboot
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="指紋認証の設定"&gt;指紋認証の設定&lt;/h3&gt;
&lt;p&gt;本 PC に搭載されている指紋リーダーは以下の Goodix 製のもの:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lsusb &lt;span class="p"&gt;|&lt;/span&gt; grep -i goodix
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Bus 003 Device 002: ID 27c6:639c Shenzhen Goodix Technology Co.,Ltd. Goodix USB2.0 MISC
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これは、比較的最近の &lt;a href="https://gitlab.freedesktop.org/libfprint/libfprint/-/releases/v1.90.7" target="_blank" rel="noopener"&gt;2020年12月にリリースされた libfprint v1.90.7&lt;/a&gt; で対応されたばかり。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://launchpad.net/ubuntu/focal/&amp;#43;source/libfprint" target="_blank" rel="noopener"&gt;Focal Fossa (20.04) 向けリリース&lt;/a&gt; での最新は 1.90.2 だったので、そのままでは使えない。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://launchpad.net/ubuntu/hirsute/&amp;#43;source/libfprint" target="_blank" rel="noopener"&gt;Hirsute Hippo (21.04) 向けリリース&lt;/a&gt; に丁度 1.90.7 が上がっていたので、これをダウンロードして使ってしまう:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /tmp
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget http://launchpadlibrarian.net/530881082/libfprint-2-2_1.90.7+git20210222+tod1-0ubuntu2_amd64.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install ./libfprint-2-2_1.90.7+git20210222+tod1-0ubuntu2_amd64.deb
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;インストール後、 &lt;code&gt;fprintd-enroll&lt;/code&gt; を実行し、指紋を登録する。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://askubuntu.com/a/1040609" target="_blank" rel="noopener"&gt;https://askubuntu.com/a/1040609&lt;/a&gt; を参考に、 &lt;code&gt;pam-auth-update&lt;/code&gt; を実行し、 &lt;code&gt;/etc/pam.d/common-auth&lt;/code&gt; を変更する。&lt;/p&gt;
&lt;p&gt;このファイルは以下を実行すると分かる通り、共通設定になっている:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg -l &lt;span class="s1"&gt;&amp;#39;@include common-auth&amp;#39;&lt;/span&gt; /etc/pam.d/ &lt;span class="p"&gt;|&lt;/span&gt; column
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/etc/pam.d/su /etc/pam.d/sudo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/etc/pam.d/gnome-screensaver /etc/pam.d/login
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/etc/pam.d/xfce4-screensaver /etc/pam.d/ppp
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/etc/pam.d/chsh /etc/pam.d/polkit-1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/etc/pam.d/other /etc/pam.d/lightdm
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/etc/pam.d/cups /etc/pam.d/chfn
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/etc/pam.d/cron /etc/pam.d/gdm-password
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;figure&gt;&lt;img src="https://www.yewton.net/2021/10/11/dell-latitude-3420-byo-ubuntu/2021-10-11_22-34-46_screenshot.png"&gt;
&lt;/figure&gt;
&lt;p&gt;こんな画面が表示されたら、 &lt;code&gt;Fingerprint authentication&lt;/code&gt; にチェックを入れて(スペースキー押下)、 &lt;code&gt;&amp;lt;Ok&amp;gt;&lt;/code&gt; する( &lt;code&gt;TAB&lt;/code&gt; で項目移動出来る )。&lt;/p&gt;
&lt;p&gt;この操作により、以下のような記述が追加されることになる:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grep fprint -C &lt;span class="m"&gt;1&lt;/span&gt; /etc/pam.d/common-auth
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# here are the per-package modules (the &amp;#34;Primary&amp;#34; block)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auth [success=2 default=ignore] pam_fprintd.so max_tries=1 timeout=10 # debug
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;auth [success=1 default=ignore] pam_unix.so nullok try_first_pass
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;以上で、ログイン時や &lt;code&gt;sudo&lt;/code&gt; する時など、大概の場面で指紋認証を使えるようになる。&lt;/p&gt;
&lt;p&gt;注意点として、まず前述の通り起動後ログイン画面(greeter)では、 &lt;strong&gt;認証成功後に Unlock ボタンを押下する必要がある&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;そして、その「認証成功」のフィードバックが分かり辛い。
パスワード入力フィールドが無くなって、 Unlock 出来そうな雰囲気になったことを察知するしかない。&lt;/p&gt;
&lt;p&gt;次に、 &lt;strong&gt;キーリングのロック解除には相変わらずパスワードが必要になる&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;これは、 &lt;a href="https://gitlab.gnome.org/GNOME/gdm/-/issues/613" target="_blank" rel="noopener"&gt;After login in with Fingerprint reader on Lenovo Thinkpad prompted to enter password for unlocking the Keyring (#613) · Issues · GNOME / gdm · GitLab&lt;/a&gt; で
議論されている通り、基本的にはセキュリティ上意図された挙動な模様。
起動直後の一度きりの入力で済む話ではあるので、当座は受け入れている。&lt;/p&gt;
&lt;p&gt;また、 &lt;strong&gt;指紋認証待ちである事のアピールが結構弱い&lt;/strong&gt; ので、タイムアウトしがちである。&lt;/p&gt;
&lt;p&gt;例えば、 &lt;code&gt;sudo&lt;/code&gt; 時は標準出力に &lt;code&gt;Place your finger on the fingerprint reader&lt;/code&gt; と控えめに出力されるだけだし、
Emacs で &lt;a href="https://www.gnu.org/software/tramp/#Using-su%5F002c-sudo%5F002c-doas-and-sg" target="_blank" rel="noopener"&gt;TRAMP を使い root 権限でファイルを開く&lt;/a&gt; ときに至っては、何も出力されない。&lt;/p&gt;
&lt;p&gt;以上のような多少の不都合はあるものの、目を瞑れる程度ではないかと思う。&lt;/p&gt;
&lt;h3 id="その他のセットアップ"&gt;その他のセットアップ&lt;/h3&gt;
&lt;p&gt;以降は、特に本機だから行うというワケではないが、記録の為に残しておく。&lt;/p&gt;
&lt;p&gt;まず何よりも先に、キーテーマを Emacs に設定する:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;xfconf-query --channel xsettings --property /Gtk/KeyThemeName --set Emacs
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;最低限のキーボードショートカットを設定する:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;xfconf-query --channel xfce4-keyboard-shortcuts --property &lt;span class="s1"&gt;&amp;#39;/commands/custom/&amp;lt;Primary&amp;gt;minus&amp;#39;&lt;/span&gt; --create --type string --set &lt;span class="s1"&gt;&amp;#39;xfce4-terminal --drop-down --hide-menubar --hide-toolbar --hide-scrollbar&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;xfconf-query --channel xfce4-keyboard-shortcuts --property &lt;span class="s1"&gt;&amp;#39;/commands/custom/&amp;lt;Primary&amp;gt;&amp;lt;Alt&amp;gt;space&amp;#39;&lt;/span&gt; --create --type string --set &lt;span class="s1"&gt;&amp;#39;xfce4-appfinder&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;xfconf-query --channel xfce4-keyboard-shortcuts --property &lt;span class="s1"&gt;&amp;#39;/commands/custom/&amp;lt;Primary&amp;gt;&amp;lt;Shift&amp;gt;&amp;lt;Alt&amp;gt;dollar&amp;#39;&lt;/span&gt; --create --type string --set &lt;span class="s1"&gt;&amp;#39;xfce4-screenshooter --clipboard --region&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;キーリピート設定を変更する:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;xfconf-query --channel keyboards --property &lt;span class="s1"&gt;&amp;#39;/Default/KeyRepeat/Delay&amp;#39;&lt;/span&gt; --create --type int --set &lt;span class="m"&gt;350&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;xfconf-query --channel keyboards --property &lt;span class="s1"&gt;&amp;#39;/Default/KeyRepeat/Rate&amp;#39;&lt;/span&gt; --create --type int --set &lt;span class="m"&gt;20&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;主に Emacs とコマンドライン系ツールの導入用に、 &lt;a href="https://guix.gnu.org/" target="_blank" rel="noopener"&gt;Guix&lt;/a&gt; を導入していく:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install nscd -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo su -
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /tmp/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget https://git.savannah.gnu.org/cgit/guix.git/plain/etc/guix-install.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod +x guix-install.sh &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; ./guix-install.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;初回はめちゃくちゃ時間かかるので、進捗確認しやすくする為にプレゼンテーションモード(自動画面オフやロックをしない)にしておく:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;xfconf-query --channel xfce4-power-manager --property /xfce4-power-manager/presentation-mode --create --type bool --set &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;初回アップデート &amp;amp; 設定:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;guix pull &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; systemctl daemon-reload &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; systemctl restart guix-daemon.service &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; guix archive --authorize &amp;lt; /root/.config/guix/current/share/guix/bordeaux.guix.gnu.org.pub &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; guix package -u &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; guix install glibc-locales &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; service lightdm restart
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ここからは通常ユーザーでの作業。&lt;/p&gt;
&lt;p&gt;引き続き Guix のアップデートと初期設定:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;guix pull &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; guix package -u
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;guix install glibc-locales nss-certs curl
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;. ~/.guix-profile/etc/profile
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;コマンドラインツール群を導入:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;guix install zsh git git:credential-libsecret rcm ripgrep fzf fasd tmux xclip direnv
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;. ~/.guix-profile/etc/profile
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install powerline -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget https://raw.githubusercontent.com/junegunn/fzf/master/shell/key-bindings.zsh -O &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/.fzf.zsh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone https://github.com/yewton/.dotfiles.git
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; .dotfiles/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;RCRC&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;~/.dotfiles/rcrc rcup
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rcup -t ubuntu
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="k"&gt;$(&lt;/span&gt;which zsh&lt;span class="k"&gt;)&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sudo tee -a /etc/shells
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chsh -s &lt;span class="k"&gt;$(&lt;/span&gt;which zsh&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ここで一旦ログアウト:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;xfce4-session-logout --logout
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ログイン後、Git の設定を行う:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git config --file ~/.gitconfig.local user.name yewton
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git config --file ~/.gitconfig.local user.email yewton@gmail.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git config --file ~/.gitconfig.local credential.helper &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/.guix-profile/bin/git-credential-libsecret
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Emacs のインストール &amp;amp; 設定:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;guix install coreutils findutils texinfo emacs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;. ~/.guix-profile/etc/profile
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install cmigemo -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir ~/.local/share/fonts
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;VER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2.5.1 &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; wget https://github.com/yuru7/HackGen/releases/download/v&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;VER&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/HackGenNerd_v&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;VER&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;.zip &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; unzip HackGenNerd_v&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;VER&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;.zip &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; mv ./HackGenNerd_v&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;VER&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/*.ttf ~/.local/share/fonts/ &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; rm -fr ./HackGenNerd_v&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;VER&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;* &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; fc-cache -fv&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone https://github.com/yewton/.emacs.d.git
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://support.1password.com/install-linux/" target="_blank" rel="noopener"&gt;Get the 1Password for Linux app&lt;/a&gt; に従い、 1Password のインストール:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -sS https://downloads.1password.com/linux/keys/1password.asc &lt;span class="p"&gt;|&lt;/span&gt; sudo gpg --dearmor --output /usr/share/keyrings/1password-archive-keyring.gpg
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;deb [arch=amd64 signed-by=/usr/share/keyrings/1password-archive-keyring.gpg] https://downloads.1password.com/linux/debian/amd64 stable main&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sudo tee /etc/apt/sources.list.d/1password.list
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo mkdir -p /etc/debsig/policies/AC2D62742012EA22/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -sS https://downloads.1password.com/linux/debian/debsig/1password.pol &lt;span class="p"&gt;|&lt;/span&gt; sudo tee /etc/debsig/policies/AC2D62742012EA22/1password.pol
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo mkdir -p /usr/share/debsig/keyrings/AC2D62742012EA22
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -sS https://downloads.1password.com/linux/keys/1password.asc &lt;span class="p"&gt;|&lt;/span&gt; sudo gpg --dearmor --output /usr/share/debsig/keyrings/AC2D62742012EA22/debsig.gpg
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo apt install 1password -y
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://asdf-vm.com/" target="_blank" rel="noopener"&gt;asdf&lt;/a&gt; のインストール:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;guix install gcc-toolchain readline zlib openssl libyaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;. ~/.guix-profile/etc/profile
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.8.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;. &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.asdf/asdf.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; i in ruby nodejs golang&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; asdf plugin-add &lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;asdf plugin-add hugo https://github.com/beardix/asdf-hugo.git
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;asdf install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;テーマを &lt;a href="https://numixproject.github.io/" target="_blank" rel="noopener"&gt;Numix&lt;/a&gt; に:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo add-apt-repository ppa:numix/ppa
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install numix-blue-gtk-theme numix-icon-theme-circle -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;xfconf-query --channel xsettings --property /Net/ThemeName --set &lt;span class="s1"&gt;&amp;#39;NumixBlue&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;xfconf-query --channel xsettings --property /Net/IconThemeName --set &lt;span class="s1"&gt;&amp;#39;Numix-Circle&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;xfconf-query --channel xfwm4 --property /general/theme --set &lt;span class="s1"&gt;&amp;#39;NumixBlue&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://github.com/google/mozc" target="_blank" rel="noopener"&gt;Mozc&lt;/a&gt; 導入:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install fcitx-mozc -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;im-config -n fcitx
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo reboot
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://docs.xfce.org/panel-plugins/xfce4-clipman-plugin/start" target="_blank" rel="noopener"&gt;xfce4-clipman-plugin&lt;/a&gt; 導入:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt intall xfce4-clipman-plugin -y
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="終わりに"&gt;終わりに&lt;/h2&gt;
&lt;p&gt;ガッツリ作業にも使えるメイン Xubuntu 機を調達出来て満足。&lt;/p&gt;
&lt;p&gt;今回の経験で問題無く使いものになることは分かったので、次回調達の機会があれば、
さらにスペックを上げたり、タッチディスプレイにすることにも検討したい。&lt;/p&gt;</description></item><item><title>スーパーマリオ64 Behind Camera Anywhere とは</title><link>https://www.yewton.net/2021/06/07/mario64-behind-camera-anywhere/</link><pubDate>Mon, 07 Jun 2021 00:30:00 +0900</pubDate><guid>https://www.yewton.net/2021/06/07/mario64-behind-camera-anywhere/</guid><description>&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;p&gt;pannenkoek2012 氏( &lt;a href="https://www.youtube.com/user/pannenkoek2012" target="_blank" rel="noopener"&gt;メインチャンネル&lt;/a&gt; , &lt;a href="https://www.youtube.com/user/pannenkeok2012" target="_blank" rel="noopener"&gt;セカンダリチャンネル&lt;/a&gt; ) の上げているマリオ 64 動画
( 極力 A ボタンを押さないプレイ、いわゆる A Button Challenge, ABC の方 )が好きで、ちょくちょく動画を拝見している。&lt;/p&gt;
&lt;p&gt;さる 2021 年 5 月 3 日に新たな動画が投稿されており、何やら新たなテクニックを活用されているようだった:&lt;/p&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/BMwzx6NCUOs?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;説明文から参照されている先を見ると、 &lt;strong&gt;Behind Camera Anywhere&lt;/strong&gt; というモノらしい:&lt;/p&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/C38He-OUAYk?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;ABC の新たな展開に備え、このテクニックを理解しようと考えた。&lt;/p&gt;
&lt;div class="ox-hugo-toc toc"&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div class="heading"&gt;&amp;#30446;&amp;#27425;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#%e8%83%8c%e6%99%af"&gt;背景&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e5%89%8d%e6%8f%90%e7%9f%a5%e8%ad%98"&gt;前提知識&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#behind-camera-anywhere"&gt;Behind Camera Anywhere&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e7%b5%82%e3%82%8f%e3%82%8a%e3%81%ab"&gt;終わりに&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e3%83%aa%e3%83%b3%e3%82%af%e9%9b%86"&gt;リンク集&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;!--endtoc--&gt;
&lt;h2 id="前提知識"&gt;前提知識&lt;/h2&gt;
&lt;p&gt;Behind Camera Anywhere は、 HOLP 固定手法の一つである。&lt;/p&gt;
&lt;p&gt;HOLP については &lt;a href="https://trap.jp/post/555/" target="_blank" rel="noopener"&gt;スーパーマリオ64学入門【アドベントカレンダー2018　32日目】 | 東京工業大学デジタル創作同好会traP&lt;/a&gt; が詳しい。&lt;/p&gt;
&lt;p&gt;簡単に説明しておくと、まず HOLP とは Held Object&amp;rsquo;s Last Place 、
つまりマリオが手に持ったオブジェクトの最終位置のこと。&lt;/p&gt;
&lt;p&gt;通常はマリオの移動と共に更新され続けるが、
何らかの理由でマリオがレンダリングされていない場合等には
HOLP が更新されずに以前の値のままになるという性質があり、
この性質を利用することを &lt;strong&gt;HOLP 固定&lt;/strong&gt; と呼ぶ。&lt;/p&gt;
&lt;p&gt;pannenkoek2012 氏による以下の動画でも解説されている:&lt;/p&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/pHihyGlYfSw?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;また、 &lt;strong&gt;HOLP はワールドをまたいでもリセットされない&lt;/strong&gt; という性質もある。&lt;/p&gt;
&lt;p&gt;この性質と、オブジェクトの消滅と保持をほぼ同時に発生させることで、
ワールド中にロードされるほぼ任意のオブジェクト(のクローン)をマリオに持たせられる技、
いわゆる &lt;strong&gt;無を取得&lt;/strong&gt; との合わせ技が ABC ではよく使われる。&lt;/p&gt;
&lt;p&gt;例えば、ポールから降りる際の A ボタン入力を回避する為に、
降りたい地点に敵オブジェクトを配置することでヒットバックを発生させ、無理矢理降りる、等である。&lt;/p&gt;
&lt;h2 id="behind-camera-anywhere"&gt;Behind Camera Anywhere&lt;/h2&gt;
&lt;p&gt;マリオを画面外に追いやることでレンダリングを回避し、
結果 HOLP を固定出来ること自体は &lt;a href="https://www.youtube.com/watch?v=pHihyGlYfSw" target="_blank" rel="noopener"&gt;先程の動画&lt;/a&gt; の公開時点(2016 年)で発見されていたものの、
その条件である「マリオを画面外に追いやる」手法が確立されていなかった。&lt;/p&gt;
&lt;p&gt;今回発見された Behind Camera Anywhere ではその名の通り、どこでもカメラの後ろに回れる、
つまり &lt;strong&gt;(ほぼ)任意の場所でマリオを画面外に追いやれる&lt;/strong&gt; ようになったのである。&lt;/p&gt;
&lt;p&gt;これまでの HOLP 固定は、 &lt;a href="https://www.youtube.com/watch?v=pHihyGlYfSw" target="_blank" rel="noopener"&gt;先程の動画&lt;/a&gt; でも紹介されているポーズバッファリングを用いたヒットスタン
(Pause Buffered Hitstun, PBH) を利用する方法が主流だった。&lt;/p&gt;
&lt;p&gt;PBH を簡単に説明すると、被弾時の点滅状態に於いて、
ゲーム内タイマーの値が偶数の場合のみマリオがレンダリングされること、
及びポーズ中でも該当タイマーの値は進み続けることを利用し、
適当な間隔でポーズを連打することで、
被弾無敵時間が持続する限り一切のレンダリングを避け、
結果として HOLP を固定する、という技である。&lt;/p&gt;
&lt;p&gt;PBH を利用するには必ず被弾する為の敵が必要になるが、
一方で今回の Behind Camera Anywhere ではそれが不要になる。&lt;/p&gt;
&lt;p&gt;とはいえ &lt;a href="https://www.youtube.com/watch?v=C38He-OUAYk" target="_blank" rel="noopener"&gt;発見元の動画&lt;/a&gt; 説明文にもある通り、
画面外を維持したまま出来る操作というのは限られており、
必ずしも PBH の代替手段とはならないのだそう。&lt;/p&gt;
&lt;p&gt;この手法にもそれなりの制限があるということではあるが、
新たな HOLP 固定手法として今後活用される機会は増えていくかもしれない。&lt;/p&gt;
&lt;h2 id="終わりに"&gt;終わりに&lt;/h2&gt;
&lt;p&gt;筆者自身はプレイするでも、解析するでもなく、
氏の解説動画を観て分かった気になっているだけである。&lt;/p&gt;
&lt;p&gt;その為、本記事の内容には誤りがある可能性もある。&lt;/p&gt;
&lt;p&gt;是非、各位自身の目で、氏による懇切丁寧な解説動画を確認し、
奥深いスーパーマリオ 64 A ボタンチャレンジの世界に飛び込んで頂きたい。&lt;/p&gt;
&lt;h2 id="リンク集"&gt;リンク集&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/user/pannenkoek2012" target="_blank" rel="noopener"&gt;pannenkoek2012 氏のメインチャンネル&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/user/pannenkeok2012" target="_blank" rel="noopener"&gt;pannenkoek2012 氏のセカンダリチャンネル&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://trap.jp/post/555/" target="_blank" rel="noopener"&gt;スーパーマリオ64学入門【アドベントカレンダー2018　32日目】 | 東京工業大学デジタル創作同好会traP&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Wowchemy 5.0.0 から 5.2.0 へのアップデート記録</title><link>https://www.yewton.net/2021/06/02/wowchemy-500-to-520/</link><pubDate>Wed, 02 Jun 2021 00:44:00 +0900</pubDate><guid>https://www.yewton.net/2021/06/02/wowchemy-500-to-520/</guid><description>&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://wowchemy.com/blog/v5.1.0/" target="_blank" rel="noopener"&gt;2021年5月4日に 5.1.0&lt;/a&gt; が、&lt;a href="https://wowchemy.com/blog/v5.2.0/" target="_blank" rel="noopener"&gt;同年5月26日に 5.2.0&lt;/a&gt; が、それぞれ発表された。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.yewton.net/2021/02/28/academic4-to-wowchemy5/"&gt;前回&lt;/a&gt; で &lt;a href="https://gohugo.io/hugo-modules/" target="_blank" rel="noopener"&gt;Hugo Modules&lt;/a&gt; への対応が済んでいるので、サクッとアップデート出来るようになった。&lt;/p&gt;
&lt;p&gt;多少、後方互換性の無い変更があるので、対応の記録を残す。&lt;/p&gt;
&lt;h2 id="アップデート手順"&gt;アップデート手順&lt;/h2&gt;
&lt;p&gt;まず、 Hugo 自体を、対応最新バージョンである v0.83.1 に上げる
( &lt;a href="https://github.com/wowchemy/wowchemy-hugo-modules/releases/tag/v5.2.0" target="_blank" rel="noopener"&gt;リリースノート&lt;/a&gt; によると、 &lt;code&gt;Hugo Extended v0.81.0-v0.83.1&lt;/code&gt; に対応している模様 )。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;netlify.toml&lt;/code&gt; の変更も忘れずに。&lt;/p&gt;
&lt;p&gt;その後、リリースノートに記載の通り以下を実行する:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo mod get github.com/wowchemy/wowchemy-hugo-modules/wowchemy@89d079b
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo mod get github.com/wowchemy/wowchemy-hugo-modules/wowchemy-cms@89d079b
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これだけだと、 &lt;code&gt;go.sum&lt;/code&gt; にゴミが残るので、更に &lt;a href="https://gohugo.io/commands/hugo%5Fmod%5Ftidy/" target="_blank" rel="noopener"&gt;hugo mod tidy&lt;/a&gt; しておくとよい。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://wowchemy.com/blog/v5.1.0/#apply-breaking-changes" target="_blank" rel="noopener"&gt;Wowchemy v5.1.0 の Apply Breaking Changes&lt;/a&gt; に従い、以下を行う:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;assets/images/&lt;/code&gt; を &lt;code&gt;assets/media/&lt;/code&gt; にリネーム&lt;/li&gt;
&lt;li&gt;デフォルトソーシャルシェア用画像の名前を &lt;code&gt;assets/media/sharing.*&lt;/code&gt; に設定し、 &lt;code&gt;sharing_image&lt;/code&gt; の設定を &lt;code&gt;config.yaml&lt;/code&gt; から削除&lt;/li&gt;
&lt;li&gt;&lt;code&gt;static/media/&lt;/code&gt; 以下のメディアファイルを、 Hugo のメディア処理システムの対象になるように &lt;code&gt;assets/media/&lt;/code&gt; に移動する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以上で、アップデートは完了となる。簡単!&lt;/p&gt;</description></item><item><title>Academic 4.8.0 から Wowchemy 5.0.0 へのアップデート記録</title><link>https://www.yewton.net/2021/02/28/academic4-to-wowchemy5/</link><pubDate>Sun, 28 Feb 2021 00:37:00 +0900</pubDate><guid>https://www.yewton.net/2021/02/28/academic4-to-wowchemy5/</guid><description>&lt;div class="ox-hugo-toc toc"&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div class="heading"&gt;&amp;#30446;&amp;#27425;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#%e8%83%8c%e6%99%af"&gt;背景&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e3%82%a2%e3%83%83%e3%83%97%e3%83%87%e3%83%bc%e3%83%88%e6%89%8b%e9%a0%86"&gt;アップデート手順&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e3%81%8a%e3%81%be%e3%81%91--chromebook-%e3%81%a7%e3%83%ad%e3%83%bc%e3%82%ab%e3%83%ab%e3%82%b5%e3%83%bc%e3%83%90%e3%83%bc%e3%81%ab%e3%82%a2%e3%82%af%e3%82%bb%e3%82%b9%e5%87%ba%e6%9d%a5%e3%81%aa%e3%81%84%e3%81%a8%e3%81%8d"&gt;(おまけ)Chromebook でローカルサーバーにアクセス出来ないとき&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e7%b5%82%e3%82%8f%e3%82%8a%e3%81%ab"&gt;終わりに&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;!--endtoc--&gt;
&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;p&gt;2021年2月25日に Wowchemy (旧 Academic) の 5.0.0 正式版が&lt;a href="https://wowchemy.com/blog/v5.0.0/" target="_blank" rel="noopener"&gt;発表された&lt;/a&gt;。
4.8 が2020年3月だったので、実に1年ぶりのアップデートとなる。&lt;/p&gt;
&lt;p&gt;Academic から Wowchemy にリブランディングされただけではなく、後方互換性の無い大幅な変更が行われている。&lt;/p&gt;
&lt;h2 id="アップデート手順"&gt;アップデート手順&lt;/h2&gt;
&lt;p&gt;公式には &lt;a href="https://wowchemy.com/blog/v5.0.0-beta.0/" target="_blank" rel="noopener"&gt;Beta 0&lt;/a&gt;、&lt;a href="https://wowchemy.com/blog/v5.0.0-beta.1/" target="_blank" rel="noopener"&gt;Beta 1&lt;/a&gt;、&lt;a href="https://wowchemy.com/blog/v5.0.0-beta.2/" target="_blank" rel="noopener"&gt;Beta 2&lt;/a&gt;、&lt;a href="https://wowchemy.com/blog/v5.0.0-beta.3/" target="_blank" rel="noopener"&gt;Beta 3&lt;/a&gt; を順に辿るとよい、とあるものの、実際のところ先の変更が後で無意味になったりしたので、改めてまとめる。&lt;/p&gt;
&lt;p&gt;まず、最大の変更点である &lt;a href="https://gohugo.io/hugo-modules/" target="_blank" rel="noopener"&gt;Hugo Modules&lt;/a&gt; への対応。&lt;/p&gt;
&lt;p&gt;1.13 以上の go をインストールした後に、
Wowchemy が対応しているバージョンの Hugo を入れる。&lt;/p&gt;
&lt;p&gt;これがパッと分からなかったのだけれど、
&lt;a href="https://wowchemy.com/blog/v5.0.0-beta.3/" target="_blank" rel="noopener"&gt;Beta 3 のリリースノート&lt;/a&gt; から Hugo 0.80.0 が最新動作確認版であることが分かり、また git 上で &lt;a href="https://github.com/wowchemy/wowchemy-hugo-modules/tree/v5.0.0" target="_blank" rel="noopener"&gt;5.0.0&lt;/a&gt; と &lt;a href="https://github.com/wowchemy/wowchemy-hugo-modules/tree/v5.0.0-beta.3" target="_blank" rel="noopener"&gt;Beta 3&lt;/a&gt; の指す先が同じであることから、
5.0.0 でも Hugo 0.80.0 が使えることが分かった。&lt;/p&gt;
&lt;p&gt;例によって extended 版が必要なので、もし arm 版が欲しい場合は &lt;a href="https://github.com/gohugoio/hugo/tree/v0.80.0" target="_blank" rel="noopener"&gt;https://github.com/gohugoio/hugo/tree/v0.80.0&lt;/a&gt; から zip をダウンロードしたのちに自身でビルドする必要がある:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;go build --tags extended
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;用意が出来たら、従来のテーマを削除する:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git submodule deinit themes/academic
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git rm themes
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;そして、 &lt;code&gt;config/_default/config.toml&lt;/code&gt; から &lt;code&gt;theme = &amp;quot;academic&amp;quot;&lt;/code&gt; の記述を削除し、以下を最下部に追加する:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;github.com/wowchemy/wowchemy-hugo-modules/wowchemy-cms&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;github.com/wowchemy/wowchemy-hugo-modules/wowchemy&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;その後に、モジュールを初期化する:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo mod init github.com/yewton/yewton.net
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これだと開発版が入ってしまうため、特定バージョンを入れ直す。&lt;/p&gt;
&lt;p&gt;Wowchemy のドキュメントにはコミットハッシュ指定で入れるように書いてあるので、何でバージョン指定出来ないんだろう、と思い調べてみたところ、どうやらバージョン指定で入れられるようなモジュール設定になっていないらしかった
(参考: &lt;a href="https://devlights.hatenablog.com/entry/2019/12/20/132730" target="_blank" rel="noopener"&gt;Goメモ-35 (モジュールのメジャーバージョンを２以降にした場合の取り扱い方について) - いろいろ備忘録日記&lt;/a&gt; )。&lt;/p&gt;
&lt;p&gt;というわけで 5.0.0 のコミットを指定して入れる…と、ここで罠があって、 &lt;strong&gt;コメント機能を使っている場合、以下の不具合の為にエラーになる&lt;/strong&gt; :&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/wowchemy/wowchemy-hugo-modules/pull/2165" target="_blank" rel="noopener"&gt;fix: comment provider never found by arhohuttunen · Pull Request #2165 · wowchemy/wowchemy-hugo-modules&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;そのため、この修正が取り込まれたコミットを指定してやる:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo mod clean
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo mod get github.com/wowchemy/wowchemy-hugo-modules/wowchemy@3cf9f6c
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo mod get github.com/wowchemy/wowchemy-hugo-modules/wowchemy-cms@3cf9f6c
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo mod tidy
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;画像置き場が &lt;code&gt;/static/img/&lt;/code&gt; &lt;code&gt;/static/media/&lt;/code&gt; に変わるので、合わせてリネーム+置換を行う。自分は &lt;a href="https://github.com/dajva/rg.el" target="_blank" rel="noopener"&gt;rg.el&lt;/a&gt; の wgrep でシュッとやってしまった。&lt;/p&gt;
&lt;p&gt;以降、細かい非互換変更への対応。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;content/authors/admin/_index.md&lt;/code&gt; の &lt;code&gt;name&lt;/code&gt; を &lt;code&gt;title&lt;/code&gt; に置換する。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;config/_default/params.toml&lt;/code&gt; に以下を追加する:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Content Management System&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;cms&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;# Enable the admin panel. See https://wowchemy.com/docs/install/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;branch&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;master&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;local_backend&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Icon Pack Extensions&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pack&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;ai&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="c"&gt;# Enable the Academicons icon pack https://jpswalsh.github.io/academicons/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;また、 &lt;code&gt;search&lt;/code&gt;, &lt;code&gt;comments&lt;/code&gt;, &lt;code&gt;map&lt;/code&gt; の設定キー &lt;code&gt;engine&lt;/code&gt; が &lt;code&gt;provider&lt;/code&gt; に変わり、また設定値が数値から文字列に変わっている。これもそれぞれ変更が必要。&lt;/p&gt;
&lt;p&gt;記事中での &lt;code&gt;alert&lt;/code&gt; ショートコードが非推奨になるので、 &lt;code&gt;callout&lt;/code&gt; に一括置換。&lt;/p&gt;
&lt;p&gt;以上で移行は完了した。&lt;/p&gt;
&lt;h2 id="おまけ--chromebook-でローカルサーバーにアクセス出来ないとき"&gt;(おまけ)Chromebook でローカルサーバーにアクセス出来ないとき&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://chromebooker.net/topics/qzy312ksxc/" target="_blank" rel="noopener"&gt;Chromebookでローカルサーバーを立てる | Chromebook情報ポータル「chromebooker」&lt;/a&gt; にある通り、
&lt;code&gt;localhost&lt;/code&gt; でアクセス出来るときもあるのだけれど、出来なくなる場合もある
(たぶん初回だけアクセス出来る？)。&lt;/p&gt;
&lt;p&gt;そんな時は昔ながらの &lt;a href="http://penguin.linux.test:1313/" target="_blank" rel="noopener"&gt;http://penguin.linux.test:1313/&lt;/a&gt; でアクセスすれば良いのだけれど、デフォルトでは hugo server は &lt;code&gt;127.0.0.1&lt;/code&gt; にバインドしているのでそのままでは拒否される。&lt;/p&gt;
&lt;p&gt;以下のように全アクセスを許可してやれば良い(信頼出来るネットワークなら):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo server -DF --bind 0.0.0.0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="終わりに"&gt;終わりに&lt;/h2&gt;
&lt;p&gt;終わってみれば、大した手間もかからずに移行出来た。&lt;/p&gt;
&lt;p&gt;とはいえ、公式ドキュメントだけだと若干引っ掛かる部分もあったので、この記録が誰かの役に立てば幸い。&lt;/p&gt;</description></item><item><title>Chromebook Acer Spin 311 に Emacs を入れて幸せになる</title><link>https://www.yewton.net/2021/02/21/acer-spin-311-emacs/</link><pubDate>Sun, 21 Feb 2021 23:24:00 +0900</pubDate><guid>https://www.yewton.net/2021/02/21/acer-spin-311-emacs/</guid><description>&lt;div class="ox-hugo-toc toc"&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div class="heading"&gt;&amp;#30446;&amp;#27425;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#emacs-%e3%81%ae%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab"&gt;Emacs のインストール&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e3%81%8a%e3%81%be%e3%81%91--git-%e3%81%ae-credential-helper-%e3%82%92%e8%a8%ad%e5%ae%9a%e3%81%99%e3%82%8b"&gt;(おまけ)git の credential helper を設定する&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e3%81%8a%e3%81%be%e3%81%91--%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88%e3%81%ae%e5%88%a9%e7%94%a8"&gt;(おまけ)スクリーンショットの利用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e3%81%8a%e3%81%be%e3%81%91--arm-%e7%89%88-hugo-extended-%e3%82%92%e4%bd%9c%e3%82%8b"&gt;(おまけ)arm 版 hugo-extended を作る&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e7%b5%82%e3%82%8f%e3%82%8a%e3%81%ab"&gt;終わりに&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;!--endtoc--&gt;
&lt;p&gt;&lt;a href="https://amzn.to/2ZBcsLU" target="_blank" rel="noopener"&gt;Chromebook Acer Spin 311&lt;/a&gt; を半ば衝動買いした。&lt;/p&gt;
&lt;p&gt;当初の目的としては、電子書籍を &lt;a href="https://play.google.com/store/apps/details?id=com.flyersoft.moonreaderp" target="_blank" rel="noopener"&gt;Moon+ Reader Pro&lt;/a&gt; で読みつつ、
&lt;a href="https://play.google.com/store/apps/details?id=com.orgzly" target="_blank" rel="noopener"&gt;Orgzly&lt;/a&gt; でメモを取り、それを &lt;a href="https://play.google.com/store/apps/details?id=com.nutomic.syncthingandroid" target="_blank" rel="noopener"&gt;Syncthing&lt;/a&gt; で共有する、というような
Android でのユースケースを、キーボード付きのデバイスでやりたいな、というくらいだった。&lt;/p&gt;
&lt;p&gt;実際購入してみたところ、 Linux (Debian) をシュッと立ち上げて使えるということだったので、それならばと Emacs を使えるようにしよう、と相成った。&lt;/p&gt;
&lt;p&gt;この Linux は本当に Debian なので、実は Chromebook 特有の何かというのはあまりなかったのだけれど、備忘録として作業内容を記録しておく。&lt;/p&gt;
&lt;h2 id="emacs-のインストール"&gt;Emacs のインストール&lt;/h2&gt;
&lt;p&gt;Linux コンテナを立ち上げたらまずは更新をかける:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt upgrade
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;日本語ロケールが設定されていないので、設定しておく:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dpkg-reconfigure locales
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Emacs や開発系のツールは新し目のを使いたいので、 nix で導入する。&lt;/p&gt;
&lt;p&gt;こういう場合に snap や flatpak 等で入れると、
Emacs 内からリンクを開く際に既存のブラウザインスタンスが使われなかったり等の変な挙動をするので、 nix を使うようにしている
(参考: &lt;a href="https://www.reddit.com/r/emacs/comments/dj3abj/opening%5Furls%5Ffrom%5Femacs%5Fin%5Ffirefox/f4lctw7?utm%5Fsource=share&amp;amp;utm%5Fmedium=web2x&amp;amp;context=3" target="_blank" rel="noopener"&gt;Opening urls from emacs in firefox : r/emacs&lt;/a&gt;)。&lt;/p&gt;
&lt;p&gt;そして、現状の ChromeOS 特有の問題として、
nix のインストールに失敗する、という物がある(参考: &lt;a href="https://github.com/NixOS/nix/issues/4107" target="_blank" rel="noopener"&gt;can&amp;rsquo;t install nix-2.3.7 on ChromeOS linux container: operation not permitted mounting /proc · Issue #4107 · NixOS/nix&lt;/a&gt;)。ここに記載の通りワークアラウンドとして以下を実行する:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo umount /proc/&lt;span class="o"&gt;{&lt;/span&gt;cpuinfo,diskstats,meminfo,stat,uptime&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これで nix のインストールが出来るようになる:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -L https://nixos.org/nix/install &lt;span class="p"&gt;|&lt;/span&gt; sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Emacs のインストールは以下の通り:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nix-env -i emacs-27.1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;インストールしたアプリを ChromeOS 側から見えるように、以下のように設定する(参考: &lt;a href="https://nixos.wiki/wiki/Installing%5FNix%5Fon%5FCrostini" target="_blank" rel="noopener"&gt;Installing Nix on Crostini - NixOS Wiki&lt;/a&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir -p ~/.config/systemd/user/cros-garcon.service.d/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat &amp;gt; ~/.config/systemd/user/cros-garcon.service.d/override.conf &lt;span class="s"&gt;&amp;lt;&amp;lt;EOF
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;[Service]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;Environment=&amp;#34;PATH=%h/.nix-profile/bin:/usr/local/sbin:/usr/local/bin:/usr/local/games:/usr/sbin:/usr/bin:/usr/games:/sbin:/bin&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;Environment=&amp;#34;XDG_DATA_DIRS=%h/.nix-profile/share:%h/.local/share:/usr/local/share:/usr/share&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これで一度再起動すれば、もう普通に使えるようになってしまう。&lt;/p&gt;
&lt;h2 id="おまけ--git-の-credential-helper-を設定する"&gt;(おまけ)git の credential helper を設定する&lt;/h2&gt;
&lt;p&gt;GitHub のプライベートリポジトリを利用する場合等には、パーソナルアクセストークンによる認証が必要になる。&lt;/p&gt;
&lt;p&gt;Chromebook でも &lt;code&gt;gnome-keyring&lt;/code&gt; を入れれば libsecret による認証ヘルパーを利用出来る。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install gnome-keyring -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/.nix-profile/share/git/contrib/credential/libsecret/ &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo make&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git config --file ~/.gitconfig.local credential.helper ~/.nix-profile/share/git/contrib/credential/libsecret/git-credential-libsecret
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これで、認証が必要なリポジトリをクローンしようとすると、以下のようなダイアログが出てくるようになる:&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2021/02/21/acer-spin-311-emacs/2021-02-21_22-11-22_screenshot.png"&gt;
&lt;/figure&gt;
&lt;h2 id="おまけ--スクリーンショットの利用"&gt;(おまけ)スクリーンショットの利用&lt;/h2&gt;
&lt;p&gt;上記のようなスクリーンショットは Chromebook 側で撮影したあとにクリップボードに送信することで、 Linux 側からも &lt;code&gt;xclip&lt;/code&gt; 等で普通に使えるようになる。&lt;/p&gt;
&lt;h2 id="おまけ--arm-版-hugo-extended-を作る"&gt;(おまけ)arm 版 hugo-extended を作る&lt;/h2&gt;
&lt;p&gt;せっかく Emacs が使えるようになったので、ブログも Chromebook で書いてしまおうと思い、
Hugo をインストールしようとした所で引っ掛かってしまった。&lt;/p&gt;
&lt;p&gt;現在利用しているテーマ( &lt;a href="https://wowchemy.com/" target="_blank" rel="noopener"&gt;Wowchemy&lt;/a&gt; )では、 Hugo の Extended 版が必要なのだが、
Spin 311 の CPU は arm であり、また Hugo 公式では arm 用の Extended バイナリを配布していない
(参考: &lt;a href="https://discourse.gohugo.io/t/extended-version-for-arm/23762" target="_blank" rel="noopener"&gt;Extended Version for ARM - support - HUGO&lt;/a&gt;)。&lt;/p&gt;
&lt;p&gt;そこで、 &lt;a href="https://apoorv.blog/posts/install-update-hugo-extended-for-arm.html" target="_blank" rel="noopener"&gt;Install Update Hugo Extended for ARM in Ubuntu | Apoorv Blog&lt;/a&gt; を参考にしつつ
(と言っても、 arm 版 go を入れて &lt;code&gt;go build --tags extended&lt;/code&gt; しましょう、というだけだが…)、ソースからビルドすることで対応した。&lt;/p&gt;
&lt;p&gt;なお、 go 自体のインストールは &lt;a href="https://github.com/asdf-vm/asdf" target="_blank" rel="noopener"&gt;asdf&lt;/a&gt; の &lt;a href="https://github.com/kennyp/asdf-golang" target="_blank" rel="noopener"&gt;Go プラグイン&lt;/a&gt; を利用した。&lt;/p&gt;
&lt;h2 id="終わりに"&gt;終わりに&lt;/h2&gt;
&lt;p&gt;Moon+ Reader で電子書籍を読みつつ、 Emacs でメモを取り、
Android の Syncthing で同期する、という面白い環境が出来上がった。&lt;/p&gt;
&lt;p&gt;ついでにブログ執筆環境も整えることが出来た。サクサク、というわけには行かないが、それほどストレスなく利用出来るし、キーボードも案外打ち易い。この記事自体も Chromebook で書いている。&lt;/p&gt;
&lt;p&gt;なかなか良い買い物だったと思う。&lt;/p&gt;</description></item><item><title>中古で12,800円の激安ノートPC(Jumper Ezbook 2)にXubuntu 20.04 LTS (Focal Fossa)を入れて幸せになる</title><link>https://www.yewton.net/2020/06/18/jumper-ezbook2-xubuntu/</link><pubDate>Thu, 18 Jun 2020 06:18:00 +0900</pubDate><guid>https://www.yewton.net/2020/06/18/jumper-ezbook2-xubuntu/</guid><description>&lt;div class="ox-hugo-toc toc"&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div class="heading"&gt;&amp;#30446;&amp;#27425;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#%e7%b5%8c%e7%b7%af"&gt;経緯&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e7%94%a8-ssd-%e3%81%ae%e5%a4%96%e4%bb%98%e3%81%91"&gt;インストール用 SSD の外付け&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#xubuntu-%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab"&gt;Xubuntu インストール&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#ezbook-%e7%94%a8%e3%81%ae-tweak"&gt;Ezbook 用の Tweak&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#xubuntu-%e3%81%ae%e5%88%9d%e6%9c%9f%e8%a8%ad%e5%ae%9a"&gt;Xubuntu の初期設定&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;!--endtoc--&gt;
&lt;h2 id="経緯"&gt;経緯&lt;/h2&gt;
&lt;p&gt;先日近所のブックオフでこんなものを見つけた。&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2020/06/18/jumper-ezbook2-xubuntu/2020-06-15_06-23-44_IMG_20200131_142511.jpg"&gt;
&lt;/figure&gt;
&lt;p&gt;値札によると、 Jumper の Ezbook というものらしい。
多分 &lt;a href="https://garumax.com/jumper-ezbook-2-review" target="_blank" rel="noopener"&gt;こちらで紹介されてる&lt;/a&gt; もの。&lt;/p&gt;
&lt;p&gt;珍しく英語配列キーボードで、 Windows 10 もついて Windows 10 単体より安い。
ということで購入を決めた。&lt;/p&gt;
&lt;p&gt;実際 &lt;a href="http://www.jp.square-enix.com/ffvii-pc-jp/" target="_blank" rel="noopener"&gt;FINAL FANTASY VII INTERNATIONAL for PC&lt;/a&gt; が快適に動かせる程度のスペックはあった。&lt;/p&gt;
&lt;p&gt;とはいえ Windows は普段遣いするモノではない(≒ Emacs を快適に使えない)ので、 Xubuntu を入れることにした。&lt;/p&gt;
&lt;p&gt;優秀なスペックとは言えないので快適というワケにはいかないが、
このブログ記事を Emacs で書きながら hugo を立ち上げ、 Gimp で画像編集をしつつ記事をプレビューする、
くらいのことは普通に出来ている。&lt;/p&gt;
&lt;p&gt;ただキーボードの反応が悪いのはいかんともしがたい。
Ctrl(Caps Lock)とスペースをよく押し損じる。
真ん中のところを押すように意識すればいいので、慣れてくれば、まあ使えないこともない…。&lt;/p&gt;
&lt;p&gt;珍しく 14 インチで、そこそこ軽いというのもあり、
雑に持ち歩けるエディタ環境という点では一定の価値があるかなー、という感じ。&lt;/p&gt;
&lt;p&gt;以下、使えるようにするまでの道程を紹介する。&lt;/p&gt;
&lt;h2 id="インストール用-ssd-の外付け"&gt;インストール用 SSD の外付け&lt;/h2&gt;
&lt;p&gt;せっかく Windows 10 が入ってるので、それは活かしておきたい。&lt;/p&gt;
&lt;p&gt;ということで、昔使っていたノート PC に入っていた &lt;a href="https://amzn.to/2AF9cpO" target="_blank" rel="noopener"&gt;TOSHIBA の SSD&lt;/a&gt; を、
&lt;a href="https://amzn.to/30RRxpF" target="_blank" rel="noopener"&gt;玄人志向 HDDケース&lt;/a&gt; で外付けドライブ化して使うことにした。&lt;/p&gt;
&lt;p&gt;相当不恰好にはなるが、適当な面ファスナーで背面に貼り付けている。&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2020/06/18/jumper-ezbook2-xubuntu/2020-06-17_03-58-14_IMG_20200617_035604.jpg"&gt;
&lt;/figure&gt;
&lt;p&gt;USB 3.0 ポートを使っているからか、それほどパフォーマンスの問題は感じない。
元々、期待するようなスペックではないというのが大きいが…。&lt;/p&gt;
&lt;p&gt;ちなみに最初は、 SSD なら何でも良かろうと思って &lt;a href="https://amzn.to/3fu9DCb" target="_blank" rel="noopener"&gt;コンパクトなエレコムの外付けSSD&lt;/a&gt; で試したが、
こちらは速度が遅くて使いものにならなかった。 Xubuntu のインストールに丸一日かかるレベル。&lt;/p&gt;
&lt;h2 id="xubuntu-インストール"&gt;Xubuntu インストール&lt;/h2&gt;
&lt;p&gt;起動用の USB ドライブの作り方は &lt;a href="https://www.yewton.net/2020/02/13/macbookpro10-xubuntu/"&gt;以前の記事&lt;/a&gt; と同様。&lt;/p&gt;
&lt;p&gt;作成した USB ドライブから起動出来るようにするには BIOS の設定を変える必要がある。&lt;/p&gt;
&lt;p&gt;起動直後の以下の画面で &lt;code&gt;ESC&lt;/code&gt; を押す。&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2020/06/18/jumper-ezbook2-xubuntu/boot.jpg"&gt;
&lt;/figure&gt;
&lt;p&gt;すると BIOS 設定画面が開くので、 &lt;code&gt;→&lt;/code&gt; キーで &lt;code&gt;Boot&lt;/code&gt; タブを開く。&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2020/06/18/jumper-ezbook2-xubuntu/bios.jpg"&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;code&gt;Boot Option Priorities&lt;/code&gt; というのが起動順を指定する設定。
&lt;code&gt;#1&lt;/code&gt; を選択して USB ドライブを指定する。&lt;/p&gt;
&lt;p&gt;後は、普通にインストール。
パーティション指定は面倒だったので、外付けドライブ全てを &lt;code&gt;/&lt;/code&gt; にした。
これでも特に問題は無さそう。&lt;/p&gt;
&lt;h2 id="ezbook-用の-tweak"&gt;Ezbook 用の Tweak&lt;/h2&gt;
&lt;p&gt;Ezbook は実はトラックパッドに特殊なキー操作が割り当たっていて、意図せず暴発するのでこれを無効にする。
具体的には上端から下へスワイプすると &lt;code&gt;Super+Down&lt;/code&gt; が押下されたことになる。
これがデフォルトでは &lt;code&gt;Tile window to the bottom&lt;/code&gt; に割り当たっているので、
&lt;code&gt;xfwm4-settings&lt;/code&gt; を立ち上げてショートカットを削除する。&lt;/p&gt;
&lt;p&gt;ちなみに、右端から左へのスワイプは &lt;code&gt;Super+A&lt;/code&gt; に、
下端から上へスワイプは &lt;code&gt;Super+B&lt;/code&gt; に、
左端から右へスワイプは &lt;code&gt;Super+TAB&lt;/code&gt; にそれぞれ割り当てられている。
これらのキーはデフォルトでは特にアサインされていなさそう。&lt;/p&gt;
&lt;p&gt;次に、 &lt;a href="https://wiki.archlinux.org/index.php/Xmodmap#Turn%5FCapsLock%5Finto%5FControl" target="_blank" rel="noopener"&gt;xmodmap - ArchWiki&lt;/a&gt; を参考にキーマップを修正する。&lt;/p&gt;
&lt;p&gt;Ezbook に限らず、 Caps Lock は Ctrl に割り当てたいので以下を &lt;code&gt;~/.Xmodmap&lt;/code&gt; に設定する:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;clear lock
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;clear control
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;keycode 66 = Control_L
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;add control = Control_L Control_R
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;即反映するには &lt;code&gt;xmodmap ~/.Xmodmap&lt;/code&gt; する。&lt;/p&gt;
&lt;p&gt;また、 Ezbook では MacBook で &lt;code&gt;/&lt;/code&gt; があるところに &lt;code&gt;Delete&lt;/code&gt; があり、
MacBook で &lt;code&gt;option&lt;/code&gt; があるところに &lt;code&gt;\&lt;/code&gt; があり使い辛くてしょうがないので、
&lt;code&gt;Delete&lt;/code&gt; を &lt;code&gt;/&lt;/code&gt; にする設定をする:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;keycode 119 = backslash bar backslash bar
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;最後に、トラックパッドのスクロール方向が直感に反するので、 &lt;code&gt;xfce4-mouse-settings&lt;/code&gt; を立ち上げ、
&lt;code&gt;Reverse scroll direction&lt;/code&gt; にチェックを入れる。&lt;/p&gt;
&lt;h2 id="xubuntu-の初期設定"&gt;Xubuntu の初期設定&lt;/h2&gt;
&lt;p&gt;まずはターミナルから Emacs キーバインドを有効にする:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;xfconf-query --channel xsettings --property /Gtk/KeyThemeName --set Emacs
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;キーボードショートカットでいつでもターミナルを出せるようにしておく:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;xfconf-query --channel xfce4-keyboard-shortcuts --property &lt;span class="s1"&gt;&amp;#39;/commands/custom/&amp;lt;Primary&amp;gt;minus&amp;#39;&lt;/span&gt; --create --type string --set &lt;span class="s1"&gt;&amp;#39;xfce4-terminal --drop-down --hide-menubar --hide-toolbar --hide-scrollbar&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;簡易 Spotlight 的な:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;xfconf-query --channel xfce4-keyboard-shortcuts --property &lt;span class="s1"&gt;&amp;#39;/commands/custom/&amp;lt;Primary&amp;gt;&amp;lt;Alt&amp;gt;space&amp;#39;&lt;/span&gt; --create --type string --set &lt;span class="s1"&gt;&amp;#39;xfce4-appfinder -c&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;キーリピート設定をする:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;xfconf-query --channel keyboards --property &lt;span class="s1"&gt;&amp;#39;/Default/KeyRepeat/Delay&amp;#39;&lt;/span&gt; --create --type int --set &lt;span class="m"&gt;350&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;xfconf-query --channel keyboards --property &lt;span class="s1"&gt;&amp;#39;/Default/KeyRepeat/Rate&amp;#39;&lt;/span&gt; --create --type int --set &lt;span class="m"&gt;20&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="http://manpages.ubuntu.com/manpages/trusty/man1/numlockx.1.html" target="_blank" rel="noopener"&gt;numlockx&lt;/a&gt; の設定をする:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;NUMLOCK&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;off &lt;span class="p"&gt;|&lt;/span&gt; sudo tee /etc/default/numlockx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://docs.brew.sh/Homebrew-on-Linux" target="_blank" rel="noopener"&gt;Linuxbrew&lt;/a&gt; を入れる:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo add-apt-repository ppa:git-core/ppa -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install curl git -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/bin/bash -c &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get install build-essential -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv)&amp;#39;&lt;/span&gt; &amp;gt;&amp;gt; &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/.profile
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="k"&gt;$(&lt;/span&gt;/home/linuxbrew/.linuxbrew/bin/brew shellenv&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;brew install gcc
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;zsh を入れる:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;brew install zsh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Git の認証ヘルパー等の設定をする:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get install libsecret-1-0 libsecret-1-dev -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /usr/share/doc/git/contrib/credential/libsecret/ &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo make&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git config --file ~/.gitconfig.local user.name yewton
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git config --file ~/.gitconfig.local user.email yewton@gmail.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git config --file ~/.gitconfig.local credential.helper /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ターミナル環境の必需品(&lt;a href="https://github.com/zplug/zplug" target="_blank" rel="noopener"&gt;zplug&lt;/a&gt;, &lt;a href="https://github.com/thoughtbot/rcm" target="_blank" rel="noopener"&gt;rcm&lt;/a&gt; , &lt;a href="https://github.com/junegunn/fzf" target="_blank" rel="noopener"&gt;fzf&lt;/a&gt; , &lt;a href="https://github.com/clvv/fasd" target="_blank" rel="noopener"&gt;fasd&lt;/a&gt; , &lt;a href="https://github.com/tmux/tmux/wiki" target="_blank" rel="noopener"&gt;tmux&lt;/a&gt; , &lt;a href="https://github.com/powerline/powerline" target="_blank" rel="noopener"&gt;powerline&lt;/a&gt; , &lt;a href="https://github.com/astrand/xclip" target="_blank" rel="noopener"&gt;xclip&lt;/a&gt;, &lt;a href="https://github.com/direnv/direnv" target="_blank" rel="noopener"&gt;direnv&lt;/a&gt;) を入れる:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget -qO - https://apt.thoughtbot.com/thoughtbot.gpg.key &lt;span class="p"&gt;|&lt;/span&gt; sudo apt-key add -
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;deb https://apt.thoughtbot.com/debian/ stable main&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sudo tee /etc/apt/sources.list.d/thoughtbot.list
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install rcm fzf fasd tmux powerline xclip direnv -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -sL --proto-redir -all,https https://raw.githubusercontent.com/zplug/installer/master/installer.zsh &lt;span class="p"&gt;|&lt;/span&gt; zsh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;source /usr/share/doc/fzf/examples/key-bindings.zsh&amp;#39;&lt;/span&gt; &amp;gt;&amp;gt; &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/.fzf.zsh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;source /usr/share/doc/fzf/examples/completion.zsh&amp;#39;&lt;/span&gt; &amp;gt;&amp;gt; &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/.fzf.zsh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://github.com/miiton/Cica" target="_blank" rel="noopener"&gt;プログラミング用日本語等幅フォント Cica(シカ)&lt;/a&gt; をインストール:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget https://github.com/miiton/Cica/releases/download/v5.0.1/Cica_v5.0.1_with_emoji.zip
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;unzip Cica_v5.0.1_with_emoji.zip
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo mv *.ttf /usr/local/share/fonts/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo fc-cache -fv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://github.com/yewton/.dotfiles" target="_blank" rel="noopener"&gt;.dotfiles&lt;/a&gt; を入れ、シェルを変更し、一度ログアウトする:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone https://github.com/yewton/.dotfiles.git
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;RCRC&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;~/.dotfiles/rcrc rcup
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rcup -t ubuntu
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="k"&gt;$(&lt;/span&gt;which zsh&lt;span class="k"&gt;)&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sudo tee -a /etc/shells
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chsh -s &lt;span class="k"&gt;$(&lt;/span&gt;which zsh&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="http://www.orgzly.com/" target="_blank" rel="noopener"&gt;Orgzly&lt;/a&gt; のノートを &lt;a href="https://syncthing.net/" target="_blank" rel="noopener"&gt;Syncthing&lt;/a&gt; で同期しているので、 Syncthing をインストールする。
&lt;code&gt;syncthing-gtk&lt;/code&gt; を入れると自動起動の設定が楽:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -s https://syncthing.net/release-key.txt &lt;span class="p"&gt;|&lt;/span&gt; sudo apt-key add -
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;deb https://apt.syncthing.net/ syncthing stable&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sudo tee /etc/apt/sources.list.d/syncthing.list
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install syncthing syncthing-gtk -y
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://app-updates.agilebits.com/product%5Fhistory/CLI" target="_blank" rel="noopener"&gt;1Password CLI&lt;/a&gt; をインストール:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget https://cache.agilebits.com/dist/1P/op/pkg/v1.1.0/op_linux_amd64_v1.1.0.zip
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;unzip op_linux_amd64_v1.1.0.zip
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mv op ~/bin/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="k"&gt;$(&lt;/span&gt;op signin my&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;1Password CLI の JSON を扱うのに便利な &lt;a href="https://github.com/Blacksmoke16/oq" target="_blank" rel="noopener"&gt;Blacksmoke16/oq&lt;/a&gt; を入れる:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;snap oq
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Firefox アカウントを取得するにはこんな感じ:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;op get item &lt;span class="s1"&gt;&amp;#39;Firefox Account&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; oq -r &lt;span class="s1"&gt;&amp;#39;.details.fields[]|select(.name==&amp;#34;username&amp;#34;)|.value&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; tr -d &lt;span class="s1"&gt;&amp;#39;\n&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; pbcopy
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;op get item &lt;span class="s1"&gt;&amp;#39;Firefox Account&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; oq -r &lt;span class="s1"&gt;&amp;#39;.details.fields[]|select(.name==&amp;#34;password&amp;#34;)|.value&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; tr -d &lt;span class="s1"&gt;&amp;#39;\n&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; pbcopy
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;op get totp &lt;span class="s1"&gt;&amp;#39;Firefox Account&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; pbcopy
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://www.gnu.org/software/emacs/" target="_blank" rel="noopener"&gt;GNU Emacs&lt;/a&gt; と関連パッケージをインストール:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install build-essential texinfo aspell ripgrep cmigemo sqlite3 -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo add-apt-repository ppa:kelleyk/emacs -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install emacs26 -y
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://github.com/yewton/.emacs.d" target="_blank" rel="noopener"&gt;.emacs.d&lt;/a&gt; や個人設定をインストールする:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone https://github.com/yewton/.emacs.d.git
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; -e &lt;span class="s2"&gt;&amp;#34;(setq custom-file \&amp;#34;~/.emacs.local/init.el\&amp;#34;)\n(load custom-file)&amp;#34;&lt;/span&gt; &amp;gt; ~/.emacs.d/custom.el
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Emacs 外での日本語入力のため &lt;a href="https://github.com/google/mozc" target="_blank" rel="noopener"&gt;Mozc&lt;/a&gt; をインストールして設定:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install -y fcitx-mozc
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;im-config -n fcitx
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo reboot &lt;span class="c1"&gt;# 一度再起動する&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;fcitx-config-gtk3 &lt;span class="c1"&gt;# 設定 GUI が立ち上がる&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://asdf-vm.com/#/" target="_blank" rel="noopener"&gt;asdf vm&lt;/a&gt; 本体とプラグインをインストール:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;brew install asdf
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;asdf plugin add ruby
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;asdf plugin add python
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;asdf plugin add nodejs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;asdf plugin add golang
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;asdf plugin add hugo https://github.com/beardix/asdf-hugo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bash -c &lt;span class="s1"&gt;&amp;#39;${ASDF_DATA_DIR:=$HOME/.asdf}/plugins/nodejs/bin/import-release-team-keyring&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;asdf install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;素敵なアイコンテーマ &lt;a href="https://github.com/numixproject/numix-icon-theme-circle" target="_blank" rel="noopener"&gt;numix-icon-theme-circle&lt;/a&gt; をインストール:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install numix-icon-theme-circle
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;アイコンテーマ以外も含めて、全部 &lt;a href="https://numixproject.github.io/" target="_blank" rel="noopener"&gt;Numix&lt;/a&gt; にするとよろしい:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;xfce4-appearance-settings
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;xfwm4-settings
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo lightdm-gtk-greeter-settings
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://github.com/dylanaraps/neofetch" target="_blank" rel="noopener"&gt;dylanaraps/neofetch&lt;/a&gt; をインストール:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install neofetch -y
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>avy で migemo る (avy-migemo を使わずに)</title><link>https://www.yewton.net/2020/05/31/avy-migemo/</link><pubDate>Sun, 31 May 2020 05:31:00 +0900</pubDate><guid>https://www.yewton.net/2020/05/31/avy-migemo/</guid><description>&lt;h2 id="tl-dr"&gt;TL;DR&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-emacs-lisp" data-lang="emacs-lisp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;avy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;migemo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;avy-goto-migemo-timer&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;&amp;amp;optional&lt;/span&gt; &lt;span class="nv"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;interactive&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;P&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;let&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;avy-all-windows&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;if&lt;/span&gt; &lt;span class="nv"&gt;arg&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;not&lt;/span&gt; &lt;span class="nv"&gt;avy-all-windows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;avy-all-windows&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;avy-with&lt;/span&gt; &lt;span class="nv"&gt;avy-goto-migemo-timer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;avy--old-cands&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;avy--read-candidates&lt;/span&gt; &lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;migemo-get-pattern&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;avy-process&lt;/span&gt; &lt;span class="nv"&gt;avy--old-cands&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-to-list&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;avy-styles-alist&lt;/span&gt; &lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;avy-goto-migemo-timer&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;pre&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;global-set-key&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;kbd&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;C-M-&amp;#39;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;avy-goto-migemo-timer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.yewton.net/2020/05/21/migemo-ivy/"&gt;以前の記事&lt;/a&gt; を書いた時点では &lt;a href="https://github.com/abo-abo/avy" target="_blank" rel="noopener"&gt;avy&lt;/a&gt; を使っていなかったが、改めて調べると超絶便利だったので使うことにした。&lt;/p&gt;
&lt;p&gt;そして当然の帰結として、 &lt;a href="http://0xcc.net/migemo/" target="_blank" rel="noopener"&gt;Migemo&lt;/a&gt; に対応させたくなった。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/momomo5717/avy-migemo" target="_blank" rel="noopener"&gt;avy-migemo&lt;/a&gt; の存在は以前から知っていたけれど、色々な機能が提供されていてよく分からなかったのと、
自分がやりたいユースケースだけ考えると複雑な仕組みは要らなさそうに思えたので、
改めて &lt;code&gt;avy&lt;/code&gt; の仕組みを調べて設定しようと考えた。&lt;/p&gt;
&lt;h2 id="やりたき事"&gt;やりたき事&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;avy&lt;/code&gt; には色々な使い方がある。&lt;/p&gt;
&lt;p&gt;1文字だけで候補を表示したり、2文字まで入力出来るようにしたり。
一定時間以内に入力された文字を候補とする、というような機能もある。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;migemo&lt;/code&gt; との組み合わせを考えると、固定の文字数よりは任意の文字数入力出来るのが望ましい。&lt;/p&gt;
&lt;p&gt;上記を踏まえると、
&lt;strong&gt;一定時間以内に入力された文字を migemo に食わせて得られた正規表現にマッチする物を候補とする&lt;/strong&gt;
ような動きが実現出来るとよさそうだった。&lt;/p&gt;
&lt;h2 id="avy-goto-char-timer"&gt;&lt;code&gt;avy-goto-char-timer&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;avy&lt;/code&gt; に組込まれている「一定時間以内に入力された文字を候補とする」関数定義を見てみる:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-emacs-lisp" data-lang="emacs-lisp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;avy-goto-char-timer&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;&amp;amp;optional&lt;/span&gt; &lt;span class="nv"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;Read one or many consecutive chars and jump to the first one.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;The window scope is determined by &lt;/span&gt;&lt;span class="ss"&gt;`avy-all-windows&amp;#39;&lt;/span&gt;&lt;span class="s"&gt; (ARG negates it).&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;interactive&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;P&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;let&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;avy-all-windows&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;if&lt;/span&gt; &lt;span class="nv"&gt;arg&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;not&lt;/span&gt; &lt;span class="nv"&gt;avy-all-windows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;avy-all-windows&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;avy-with&lt;/span&gt; &lt;span class="nv"&gt;avy-goto-char-timer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;avy--old-cands&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;avy--read-candidates&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;avy-process&lt;/span&gt; &lt;span class="nv"&gt;avy--old-cands&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;案外短い。&lt;/p&gt;
&lt;p&gt;キモは &lt;code&gt;avy--read-candidates&lt;/code&gt; で、こいつはオプショナルで文字列から正規表現を作る関数を指定出来る。
ここで &lt;code&gt;migemo-get-pattern&lt;/code&gt; を食わせてやればいい。&lt;/p&gt;
&lt;h2 id="migemo-を使って候補を表示する独自関数"&gt;migemo を使って候補を表示する独自関数&lt;/h2&gt;
&lt;p&gt;というわけで冒頭の独自関数を定義する:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-emacs-lisp" data-lang="emacs-lisp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;avy-goto-migemo-timer&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;&amp;amp;optional&lt;/span&gt; &lt;span class="nv"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;interactive&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;P&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;let&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;avy-all-windows&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;if&lt;/span&gt; &lt;span class="nv"&gt;arg&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;not&lt;/span&gt; &lt;span class="nv"&gt;avy-all-windows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;avy-all-windows&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;avy-with&lt;/span&gt; &lt;span class="nv"&gt;avy-goto-migemo-timer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;avy--old-cands&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;avy--read-candidates&lt;/span&gt; &lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;migemo-get-pattern&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;avy-process&lt;/span&gt; &lt;span class="nv"&gt;avy--old-cands&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;avy-goto-char-timer&lt;/code&gt; をほんの一部書き換えただけ。&lt;/p&gt;
&lt;p&gt;デフォルトだと候補のキーは文字に重ねて表示されるが、
migemo で引っ掛けたいような文字は入力した文字とは異なる場合が多い。
そのため重ねずに前方に表示するようにしたいため、明示的にスタイルを設定しておく:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-emacs-lisp" data-lang="emacs-lisp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-to-list&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;avy-styles-alist&lt;/span&gt; &lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;avy-goto-migemo-timer&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;pre&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>counsel-rg と migemo を組み合わせて ripgrep でもローマ字検索</title><link>https://www.yewton.net/2020/05/25/counsel-rg-migemo/</link><pubDate>Mon, 25 May 2020 06:51:00 +0900</pubDate><guid>https://www.yewton.net/2020/05/25/counsel-rg-migemo/</guid><description>&lt;p&gt;&lt;a href="https://www.yewton.net/2020/05/21/migemo-ivy/"&gt;Ivy (Swiper) で雑に migemo を使う&lt;/a&gt; の続編。併せて参照のコト。&lt;/p&gt;
&lt;h2 id="tl-dr"&gt;TL;DR&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-emacs-lisp" data-lang="emacs-lisp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;migemo-options&lt;/span&gt; &lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;--quiet&amp;#34;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;--nonewline&amp;#34;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;--emacs&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;ivy-re-builders-alist&lt;/span&gt; &lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="no"&gt;t&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;ivy--regex-plus&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;counsel-rg&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;ytn-ivy-migemo-re-builder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;swiper&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;ytn-ivy-migemo-re-builder&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="counsel-rg-の仕組み"&gt;counsel-rg の仕組み&lt;/h2&gt;
&lt;p&gt;Emacs で使える正規表現と rg に渡せる正規表現は異なるのに、
そもそも一体どうやって &lt;code&gt;counsel-rg&lt;/code&gt; が実現されているかを確認した。&lt;/p&gt;
&lt;p&gt;すると、 &lt;code&gt;counsel--elisp-to-pcre&lt;/code&gt; という関数で、
Emacs 式正規表現を &lt;a href="https://www.pcre.org/" target="_blank" rel="noopener"&gt;PCRE (Perl Compatible Regular Expressions)&lt;/a&gt; にベストエフォートで変換してくれている。&lt;/p&gt;
&lt;h2 id="migemo--cmigemo--が出力する正規表現と-pcre-非互換の問題"&gt;migemo(cmigemo) が出力する正規表現と、 PCRE 非互換の問題&lt;/h2&gt;
&lt;p&gt;デフォルトでは以下のような正規表現が出力される:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ cmigemo -d &amp;#39;/usr/local/Cellar/cmigemo/20110227/share/migemo/utf-8/migemo-dict&amp;#39; --quiet --emacs --word wagahai
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;\(ﾜ\s-*ｶ\s-*ﾞ\s-*ﾊ\s-*ｲ\|ワ\s-*ガ\s-*ハ\s-*イ\|吾\s-*\(輩\|が\s-*輩\)\|我\s-*\(輩\|が\s-*輩\)\|わ\s-*が\s-*は\s-*い\|ｗ\s-*ａ\s-*ｇ\s-*ａ\s-*ｈ\s-*ａ\s-*ｉ\|w\s-*a\s-*g\s-*a\s-*h\s-*a\s-*i\)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これは、空白や改行を挟んでいてもマッチするようにするため。&lt;/p&gt;
&lt;p&gt;この &lt;code&gt;\s-&lt;/code&gt; というのは Emacs 独自のもので、シンタックステーブルを利用したマッチの仕組み:&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;‘\sCODE’
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; matches any character whose syntax is CODE. Here CODE is a
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; character that represents a syntax code: thus, ‘w’ for word
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; constituent, ‘-’ for whitespace, ‘(’ for open parenthesis, etc. To
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; represent whitespace syntax, use either ‘-’ or a space character.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; *Note Syntax Class Table::, for a list of syntax codes and the
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; characters that stand for them.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;\s-&lt;/code&gt; は構文上ホワイトスペース扱いされる文字にマッチする。&lt;/p&gt;
&lt;p&gt;これは当然、他の正規表現エンジンでは使えない。&lt;/p&gt;
&lt;p&gt;PCRE では &lt;code&gt;\s&lt;/code&gt; がホワイトスペースにマッチするので(参考: &lt;a href="https://www.pcre.org/original/doc/html/pcrepattern.html#genericchartypes" target="_blank" rel="noopener"&gt;pcrepattern specification&lt;/a&gt;)、
&lt;code&gt;\s-&lt;/code&gt; を &lt;code&gt;\s&lt;/code&gt; で置換する、という手もあるけれど、
そもそも ripgrep や Swiper を使うときに、ホワイトスペースが間に挟まる場合を考慮したくなるということは少ないと思うので、
複数行を考慮させないようにするという方向で調整したい。&lt;/p&gt;
&lt;h2 id="migemo--cmigemo--で複数行に渡る文字列を考慮しないようにする"&gt;migemo(cmigemo) で複数行に渡る文字列を考慮しないようにする&lt;/h2&gt;
&lt;p&gt;そのものズバリなオプションが用意されている:&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-n --nonewline Don&amp;#39;t use newline match.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;p&gt;このオプションを指定すると、出力される正規表現は以下のようになる:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cmigemo -d &amp;#39;/usr/local/Cellar/cmigemo/20110227/share/migemo/utf-8/migemo-dict&amp;#39; --quiet --emasc --nonewline --word wagahai
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(ﾜｶﾞﾊｲ|ワガハイ|吾(輩|が輩)|我(輩|が輩)|わがはい|ｗａｇａｈａｉ|wagahai)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;あとは、このオプションを &lt;code&gt;migemo-options&lt;/code&gt; に指定すればよい:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-emacs-lisp" data-lang="emacs-lisp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;migemo-options&lt;/span&gt; &lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;--quiet&amp;#34;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;--nonewline&amp;#34;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;--emacs&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;なお、すでに &lt;code&gt;migemo-init&lt;/code&gt; している場合は反映されないので、その場合は一度 &lt;code&gt;migemo-kill&lt;/code&gt; する必要がある。&lt;/p&gt;</description></item><item><title>Ivy (Swiper) で雑に migemo を使う</title><link>https://www.yewton.net/2020/05/21/migemo-ivy/</link><pubDate>Thu, 21 May 2020 04:50:00 +0900</pubDate><guid>https://www.yewton.net/2020/05/21/migemo-ivy/</guid><description>&lt;p class="mylastmod"&gt; 27, 2021 最終更新&lt;/p&gt;
&lt;div class="callout flex px-4 py-3 mb-6 rounded-md border-l-4 bg-blue-100 dark:bg-blue-900 border-blue-500"
data-callout="note"
data-callout-metadata=""&gt;
&lt;span class="callout-icon pr-3 pt-1 text-blue-600 dark:text-blue-300"&gt;
&lt;svg height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&gt;&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="m16.862 4.487l1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8l.8-2.685a4.5 4.5 0 0 1 1.13-1.897zm0 0L19.5 7.125"/&gt;&lt;/svg&gt;
&lt;/span&gt;
&lt;div class="callout-content dark:text-neutral-300"&gt;
&lt;div class="callout-title font-semibold mb-1"&gt;Note&lt;/div&gt;
&lt;div class="callout-body"&gt;&lt;p&gt;&lt;a href="https://www.yewton.net/2020/05/24/counsel-rg-migemo/"&gt;counsel-rg と migemo を組み合わせて ripgrep でもローマ字検索&lt;/a&gt; も併せて参照。&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="tl-dr"&gt;TL;DR&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-emacs-lisp" data-lang="emacs-lisp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;reqiure&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;dash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;ytn-ivy-migemo-re-builder&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;let*&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;sep&lt;/span&gt; &lt;span class="s"&gt;&amp;#34; \\|\\^\\|\\.\\|\\*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;splitted&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--map&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;s-join&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span class="nv"&gt;it&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--partition-by&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;s-matches-p&lt;/span&gt; &lt;span class="s"&gt;&amp;#34; \\|\\^\\|\\.\\|\\*&amp;#34;&lt;/span&gt; &lt;span class="nv"&gt;it&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;s-split&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span class="nv"&gt;str&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;s-join&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--map&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cond&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;s-equals?&lt;/span&gt; &lt;span class="nv"&gt;it&lt;/span&gt; &lt;span class="s"&gt;&amp;#34; &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;.*?&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;s-matches?&lt;/span&gt; &lt;span class="nv"&gt;sep&lt;/span&gt; &lt;span class="nv"&gt;it&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;it&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;t&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;migemo-get-pattern&lt;/span&gt; &lt;span class="nv"&gt;it&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;splitted&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;ivy-re-builders-alist&lt;/span&gt; &lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="no"&gt;t&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;ivy--regex-plus&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;swiper&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;ytn-ivy-migemo-re-builder&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;p&gt;Swiper で migemo を使おうと思ってググると &lt;a href="https://github.com/momomo5717/avy-migemo" target="_blank" rel="noopener"&gt;avy-migemo&lt;/a&gt; での設定例しか出てこない。&lt;/p&gt;
&lt;p&gt;個人的には avy を使っていない(使えていない)のと、
Swiper を使いたいのに avy が絡んでくるっていうのがよく分からなかったので利用するのが憚られた。&lt;/p&gt;
&lt;p&gt;そこで、 ivy の仕組みをちゃんと理解してやってみようと思った。&lt;/p&gt;
&lt;h2 id="migemo-の仕組み"&gt;migemo の仕組み&lt;/h2&gt;
&lt;p&gt;migemo 自体の仕組みは超単純で、 &lt;a href="http://0xcc.net/migemo/" target="_blank" rel="noopener"&gt;Migemo: ローマ字のまま日本語をインクリメンタル検索&lt;/a&gt; で解説されている通り:&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;利用者が 1文字入力するたびに、ローマ字列から正規表現を生成して、それで検索するという力技な方法です。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;この正規表現を取得するには &lt;code&gt;migemo-get-pattern&lt;/code&gt; を使う:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ELISP&amp;gt; (migemo-get-pattern &amp;#34;ebihurai&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;#34;\\(ｴ\\s-*ﾋ\\s-*ﾞ\\s-*ﾌ\\s-*ﾗ\\s-*ｲ\\|エ\\s-*ビ\\s-*フ\\s-*ラ\\s-*イ\\|海\\s-*老\\s-*フ\\s-*ラ\\s-*イ\\|え\\s-*び\\s-*ふ\\s-*ら\\s-*い\\|ｅ\\s-*ｂ\\s-*ｉ\\s-*ｈ\\s-*ｕ\\s-*ｒ\\s-*ａ\\s-*ｉ\\|e\\s-*b\\s-*i\\s-*h\\s-*u\\s-*r\\s-*a\\s-*i\\)&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="ivy-の仕組み"&gt;ivy の仕組み&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;ivy-read&lt;/code&gt; という関数が、入力からいい感じの正規表現を使って検索してくれるフロントエンド。&lt;/p&gt;
&lt;p&gt;そこで使われる正規表現は、 &lt;code&gt;ivy-alist-setting&lt;/code&gt; を通して &lt;code&gt;ivy-re-builders-alist&lt;/code&gt; から取得される。&lt;/p&gt;
&lt;p&gt;Swiper の場合はこんな感じ:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-emacs-lisp" data-lang="emacs-lisp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;ivy-read&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;Swiper: &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;candidates&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;:initial-input&lt;/span&gt; &lt;span class="nv"&gt;initial-input&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;:keymap&lt;/span&gt; &lt;span class="nv"&gt;swiper-map&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;:preselect&lt;/span&gt; &lt;span class="nv"&gt;preselect&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;:require-match&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;:update-fn&lt;/span&gt; &lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;swiper--update-input-ivy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;:unwind&lt;/span&gt; &lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;swiper--cleanup&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;:action&lt;/span&gt; &lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;swiper--action&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;:re-builder&lt;/span&gt; &lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;swiper--re-builder&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;:history&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;swiper-history&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;:caller&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;swiper&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;migemo を使いたいのは今のところ Swiper だけなので、 &lt;code&gt;'swiper&lt;/code&gt; をキーにして独自関数を設定すればいい。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-emacs-lisp" data-lang="emacs-lisp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;ivy-re-builders-alist&lt;/span&gt; &lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="no"&gt;t&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;ivy--regex-plus&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;swiper&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;ytn-ivy-migemo-re-builder&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="migemo-を使って検索する独自関数"&gt;migemo を使って検索する独自関数&lt;/h2&gt;
&lt;p&gt;Swiper はスペースで区切って雑に絞り込んでいけるというのが最大の(個人的な)メリットなので、最低限それを実現出来ればよかった。&lt;/p&gt;
&lt;p&gt;実は &lt;code&gt;!&lt;/code&gt; で exclude を実現出来たり色々他にも気の効いた機能があるみたいだけれど、自分は使っていない(そこまで使いこなせてない)。&lt;/p&gt;
&lt;p&gt;なので、空白や正規表現っぽい入力は as-is にして、それ以外の入力を migemo に食わせてやり、最後に空白を &lt;code&gt;.*?&lt;/code&gt; に変換して結合した文字列を最終的な正規表現とする。&lt;/p&gt;
&lt;p&gt;というのを実現しようとするとこんな感じになる:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-emacs-lisp" data-lang="emacs-lisp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;ytn-ivy-migemo-re-builder&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;let*&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;sep&lt;/span&gt; &lt;span class="s"&gt;&amp;#34; \\|\\^\\|\\.\\|\\*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;splitted&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--map&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;s-join&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span class="nv"&gt;it&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--partition-by&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;s-matches-p&lt;/span&gt; &lt;span class="s"&gt;&amp;#34; \\|\\^\\|\\.\\|\\*&amp;#34;&lt;/span&gt; &lt;span class="nv"&gt;it&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;s-split&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span class="nv"&gt;str&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;s-join&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--map&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cond&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;s-equals?&lt;/span&gt; &lt;span class="nv"&gt;it&lt;/span&gt; &lt;span class="s"&gt;&amp;#34; &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;.*?&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;s-matches?&lt;/span&gt; &lt;span class="nv"&gt;sep&lt;/span&gt; &lt;span class="nv"&gt;it&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;it&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;t&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;migemo-get-pattern&lt;/span&gt; &lt;span class="nv"&gt;it&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;splitted&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>MacBook Pro (Retina, 15-inch, Mid 2012) で macOS と Xubuntu 19.10 Eoan Ermine をデュアルブートする</title><link>https://www.yewton.net/2020/02/13/macbookpro10-xubuntu/</link><pubDate>Thu, 13 Feb 2020 07:01:00 +0900</pubDate><guid>https://www.yewton.net/2020/02/13/macbookpro10-xubuntu/</guid><description>&lt;div class="ox-hugo-toc toc"&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div class="heading"&gt;&amp;#30446;&amp;#27425;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#%e5%89%8d%e6%8f%90"&gt;前提&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e3%83%91%e3%83%bc%e3%83%86%e3%82%a3%e3%82%b7%e3%83%a7%e3%83%b3%e3%81%ae%e5%88%86%e5%89%b2"&gt;パーティションの分割&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e8%b5%b7%e5%8b%95%e7%94%a8usb%e3%83%89%e3%83%a9%e3%82%a4%e3%83%96%e3%81%ae%e4%bd%9c%e6%88%90"&gt;起動用USBドライブの作成&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#xubuntu-%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab"&gt;Xubuntu インストール&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#xubuntu-%e5%88%9d%e6%9c%9f%e8%a8%ad%e5%ae%9a"&gt;Xubuntu 初期設定&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#%e3%82%ad%e3%83%bc%e3%83%86%e3%83%bc%e3%83%9e%e3%82%92emacs%e9%a2%a8--macos%e9%a2%a8--%e3%81%ab%e3%81%99%e3%82%8b"&gt;キーテーマをEmacs風(macOS風)にする&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e3%82%bf%e3%83%83%e3%83%81%e3%83%91%e3%83%83%e3%83%89%e3%81%ae%e8%a8%ad%e5%ae%9a--%e3%83%8a%e3%83%81%e3%83%a5%e3%83%a9%e3%83%ab%e3%82%b9%e3%82%af%e3%83%ad%e3%83%bc%e3%83%ab-%e6%b0%b4%e5%b9%b3%e3%82%b9%e3%82%af%e3%83%ad%e3%83%bc%e3%83%ab"&gt;タッチパッドの設定(ナチュラルスクロール、水平スクロール)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e3%82%ad%e3%83%bc%e3%83%9c%e3%83%bc%e3%83%89%e3%81%ae%e8%a8%ad%e5%ae%9a--%e3%83%95%e3%82%a1%e3%83%b3%e3%82%af%e3%82%b7%e3%83%a7%e3%83%b3%e3%82%ad%e3%83%bc%e3%81%ae%e6%9c%89%e5%8a%b9%e5%8c%96"&gt;キーボードの設定(ファンクションキーの有効化)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#macos-dock-%e9%a2%a8%e3%81%ae%e3%83%a9%e3%83%b3%e3%83%81%e3%83%a3--plank"&gt;macOS Dock 風のランチャ(Plank)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#alfred-spotlight-%e9%a2%a8%e3%81%ae%e3%83%a9%e3%83%b3%e3%83%81%e3%83%a3--albert"&gt;Alfred, Spotlight 風のランチャ(Albert)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#cica-%e3%83%95%e3%82%a9%e3%83%b3%e3%83%88%e3%81%ae%e8%bf%bd%e5%8a%a0"&gt;Cica フォントの追加&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#asdf-%e3%81%ae%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e3%81%a8%e8%a8%ad%e5%ae%9a"&gt;asdf のインストールと設定&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#emacs-%e3%81%ae%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e3%81%a8%e8%a8%ad%e5%ae%9a"&gt;Emacs のインストールと設定&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e3%82%bf%e3%83%bc%e3%83%9f%e3%83%8a%e3%83%ab%e9%96%a2%e9%80%a3%e3%81%ae%e8%a8%ad%e5%ae%9a"&gt;ターミナル関連の設定&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#git-%e3%81%ae%e8%aa%8d%e8%a8%bc%e3%83%98%e3%83%ab%e3%83%91%e8%a8%ad%e5%ae%9a"&gt;git の認証ヘルパ設定&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#hidpi-%e3%81%b8%e3%81%ae%e5%af%be%e5%bf%9c"&gt;HiDPI への対応&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e5%8f%82%e8%80%83%e3%81%ab%e3%81%97%e3%81%9f%e3%83%aa%e3%83%b3%e3%82%af%e9%9b%86"&gt;参考にしたリンク集&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;!--endtoc--&gt;
&lt;h2 id="前提"&gt;前提&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;MacBook Pro の種類は &lt;a href="https://support.apple.com/kb/SP653?locale=ja%5FJP" target="_blank" rel="noopener"&gt;15インチMacBook Pro Retinaディスプレイモデル：2.6GHz&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;OS は &lt;a href="https://support.apple.com/ja-jp/HT206886" target="_blank" rel="noopener"&gt;OS X El Capitan&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Xubuntu は &lt;a href="https://xubuntu.org/news/xubuntu-19-10-released/" target="_blank" rel="noopener"&gt;Xubuntu 19.10 Eoan Ermine&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;目玉は &lt;code&gt;improved HiDPI support&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="パーティションの分割"&gt;パーティションの分割&lt;/h2&gt;
&lt;p&gt;まず &lt;strong&gt;&lt;a href="https://support.apple.com/ja-jp/HT204837" target="_blank" rel="noopener"&gt;FileVault&lt;/a&gt; が有効な状態ではパーティション操作が出来ない&lt;/strong&gt; ので、システム設定から解除する。
解除するだけで数時間かかるので気長に待つ。&lt;/p&gt;
&lt;p&gt;FileVault の無効化が済んだら、 &lt;a href="https://support.apple.com/ja-jp/guide/disk-utility/welcome/mac" target="_blank" rel="noopener"&gt;Mac 用ディスクユーティリティ&lt;/a&gt; を使って Xubuntu インストール用のパーティションを用意する。&lt;/p&gt;
&lt;p&gt;初期状態だとパーティション作成メニューが選択出来ないので、
&lt;a href="https://apple.stackexchange.com/questions/304131/no-partition-scheme-option-when-erasing-a-usb-disk-in-macos-high-sierra" target="_blank" rel="noopener"&gt;No partition scheme option when erasing a USB disk in MacOS High Sierra? - Ask Different&lt;/a&gt; を参考に
全てのデバイスを表示し、 &lt;strong&gt;ボリュームではなくディスクを選択&lt;/strong&gt; する。&lt;/p&gt;
&lt;p&gt;今回は単純に半分を mac に、もう半分を Xubuntu で使うように二等分した。
パーティション追加時の初期状態のまま。&lt;/p&gt;
&lt;p&gt;このパーティション分割も数時間かかるので気長に待つ。&lt;/p&gt;
&lt;h2 id="起動用usbドライブの作成"&gt;起動用USBドライブの作成&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;xubuntu-19.10-desktop-amd64.iso&lt;/code&gt; を &lt;a href="https://xubuntu.org/download" target="_blank" rel="noopener"&gt;Xubuntu 公式サイト&lt;/a&gt; からダウンロードする。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://ubuntu.com/tutorials/tutorial-create-a-usb-stick-on-macos" target="_blank" rel="noopener"&gt;Create a bootable USB stick on macOS | Ubuntu&lt;/a&gt; を参考に、 &lt;a href="https://www.balena.io/etcher/" target="_blank" rel="noopener"&gt;Etcher&lt;/a&gt; で上記の OS イメージを焼く。&lt;/p&gt;
&lt;p&gt;用意したのは容量 2GB という骨董品レベルの USB スティックドライブだったが、問題なく動いた。&lt;/p&gt;
&lt;h2 id="xubuntu-インストール"&gt;Xubuntu インストール&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://support.apple.com/ja-jp/HT202796" target="_blank" rel="noopener"&gt;Startup Manager&lt;/a&gt; を起動し、上記の起動USBドライブを挿入する。&lt;/p&gt;
&lt;p&gt;すると下の画像のように黄色い &lt;code&gt;EFI Boot&lt;/code&gt; という名前のドライブが出現するので、
これを選択する。&lt;/p&gt;
&lt;p&gt;何故か二つ出現することがあるのだが、どちらを選んでも大丈夫そうだった。&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2020/02/13/macbookpro10-xubuntu/2020-02-13_04-45-56_startup-manager.jpg"&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;初期状態では Wi-Fi が使えない&lt;/strong&gt; はずなので、 &lt;a href="https://amzn.to/2OPxvW3" target="_blank" rel="noopener"&gt;Rankie の有線LAN アダプタ&lt;/a&gt; など
ドライバのインストール不要な適当な USB イーサネットアダプタを用意しておく必要がある。&lt;/p&gt;
&lt;p&gt;インストール時に
&lt;code&gt;グラフィックスとWi-Fiハードウェアと追加のメディアフォーマットのサードパーティ製ソフトウェアをインストールする&lt;/code&gt; をチェックしておくと、
初回起動時から Wi-Fi が使えるようになる模様。&lt;/p&gt;
&lt;p&gt;いずれにしても有線環境は必要。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://help.ubuntu.com/community/SwapFaq" target="_blank" rel="noopener"&gt;SwapFaq - Community Help Wiki&lt;/a&gt; を参考に以下のように &lt;code&gt;swap&lt;/code&gt; パーティションだけ用意したが、
別に要らなかったかもしれない。あとから &lt;a href="https://wiki.archlinux.org/index.php/Swap#Swap%5Ffile" target="_blank" rel="noopener"&gt;SwapFile&lt;/a&gt; を追加することも出来るようだし。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ブートローダをインストールするデバイス&lt;/code&gt; は Xubuntu のルートパーティションを選択した。&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2020/02/13/macbookpro10-xubuntu/2020-02-13_04-47-05_IMG_20200211_045148.jpg"&gt;
&lt;/figure&gt;
&lt;p&gt;インストール完了後はデフォルトで Xubuntu が起動するようになる。&lt;/p&gt;
&lt;p&gt;変えたくなったら再び Startup Manager を起動すればよい。&lt;/p&gt;
&lt;h2 id="xubuntu-初期設定"&gt;Xubuntu 初期設定&lt;/h2&gt;
&lt;h3 id="キーテーマをemacs風--macos風--にする"&gt;キーテーマをEmacs風(macOS風)にする&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;xfconf-query -c xsettings -p /Gtk/KeyThemeName -s Emacs
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="タッチパッドの設定--ナチュラルスクロール-水平スクロール"&gt;タッチパッドの設定(ナチュラルスクロール、水平スクロール)&lt;/h3&gt;
&lt;p&gt;以下のようなシェルスクリプトを作成し、 &lt;code&gt;セッションと起動&lt;/code&gt; メニューからログイン時に実行するように設定する。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/usr/bin/env bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;synclient &lt;span class="nv"&gt;VertScrollDelta&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;-&lt;span class="k"&gt;$(&lt;/span&gt;synclient &lt;span class="p"&gt;|&lt;/span&gt; grep VertScrollDelta &lt;span class="p"&gt;|&lt;/span&gt; awk &lt;span class="s1"&gt;&amp;#39;{print $3}&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;synclient &lt;span class="nv"&gt;HorizTwoFingerScroll&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;synclient &lt;span class="nv"&gt;HorizScrollDelta&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;-&lt;span class="k"&gt;$(&lt;/span&gt;synclient &lt;span class="p"&gt;|&lt;/span&gt; grep HorizScrollDelta &lt;span class="p"&gt;|&lt;/span&gt; awk &lt;span class="s1"&gt;&amp;#39;{print $3}&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="src-block-caption"&gt;
&lt;span class="src-block-number"&gt;ソースコード 1&lt;/span&gt;:
&lt;code&gt;fix_scroll.sh&lt;/code&gt;
&lt;/div&gt;
&lt;h3 id="キーボードの設定--ファンクションキーの有効化"&gt;キーボードの設定(ファンクションキーの有効化)&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;options hid_apple fnmode=2&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sudo tee -a /etc/modprobe.d/hid_apple.conf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="macos-dock-風のランチャ--plank"&gt;macOS Dock 風のランチャ(Plank)&lt;/h3&gt;
&lt;p&gt;シンプルな Dock 風のランチャ &lt;a href="https://launchpad.net/plank" target="_blank" rel="noopener"&gt;Plank&lt;/a&gt; をインストールし、 &lt;code&gt;セッションと起動&lt;/code&gt; メニューからログイン時に実行するように設定する。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install plank
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="alfred-spotlight-風のランチャ--albert"&gt;Alfred, Spotlight 風のランチャ(Albert)&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.alfredapp.com/" target="_blank" rel="noopener"&gt;Alfred&lt;/a&gt; や &lt;a href="https://support.apple.com/ja-jp/HT204014" target="_blank" rel="noopener"&gt;Spotlight&lt;/a&gt; のような使い心地のランチャ &lt;a href="https://albertlauncher.github.io/" target="_blank" rel="noopener"&gt;Albert&lt;/a&gt; をインストールし、 &lt;code&gt;セッションと起動&lt;/code&gt; メニューからログイン時に実行するように設定する。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl https://build.opensuse.org/projects/home:manuelschneid3r/public_key &lt;span class="p"&gt;|&lt;/span&gt; sudo apt-key add -
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;deb http://download.opensuse.org/repositories/home:/manuelschneid3r/xUbuntu_19.10/ /&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sudo tee /etc/apt/sources.list.d/home:manuelschneid3r.list
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt install albert
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="cica-フォントの追加"&gt;Cica フォントの追加&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://github.com/miiton/Cica" target="_blank" rel="noopener"&gt;miiton/Cica: プログラミング用日本語等幅フォント Cica(シカ)&lt;/a&gt; をインストールする。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget https://github.com/miiton/Cica/releases/download/v5.0.1/Cica_v5.0.1_with_emoji.zip
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;unzip Cica_v5.0.1_with_emoji.zip
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo mv *.ttf /usr/local/share/fonts/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo fc-cache -fv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="asdf-のインストールと設定"&gt;asdf のインストールと設定&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://asdf-vm.com/#/core-manage-asdf-vm" target="_blank" rel="noopener"&gt;asdf&lt;/a&gt; をインストールし、プラグインに必要なパッケージをインストールする。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; automake autoconf libreadline-dev &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; libncurses-dev libssl-dev libyaml-dev &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; libxslt-dev libffi-dev libtool unixodbc-dev &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; unzip curl &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; libbz2-dev libreadline-dev libsqlite3-dev -y
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="emacs-のインストールと設定"&gt;Emacs のインストールと設定&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.gnu.org/software/emacs/" target="_blank" rel="noopener"&gt;GNU Emacs&lt;/a&gt; をインスールし、利用するパッケージをインストールする。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install build-essential texinfo aspell ripgrep cmigemo -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo snap install emacs --classic
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="ターミナル関連の設定"&gt;ターミナル関連の設定&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget -qO - https://apt.thoughtbot.com/thoughtbot.gpg.key &lt;span class="p"&gt;|&lt;/span&gt; sudo apt-key add -
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;deb https://apt.thoughtbot.com/debian/ stable main&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sudo tee /etc/apt/sources.list.d/thoughtbot.list
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install rcm curl fzf fasd tmux powerline -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -sL --proto-redir -all,https https://raw.githubusercontent.com/zplug/installer/master/installer.zsh &lt;span class="p"&gt;|&lt;/span&gt; zsh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;fzf は &lt;code&gt;/usr/share/doc/fzf/README.Debian&lt;/code&gt; にある指示に従う。&lt;/p&gt;
&lt;h3 id="git-の認証ヘルパ設定"&gt;git の認証ヘルパ設定&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get install libsecret-1-0 libsecret-1-dev
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /usr/share/doc/git/contrib/credential/libsecret/ &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo make&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; -e &lt;span class="s2"&gt;&amp;#34;\n[credential]\n helper = /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret\n&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; ~/.gitconfig.local
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="hidpi-への対応"&gt;HiDPI への対応&lt;/h3&gt;
&lt;h4 id="全般"&gt;全般&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;外観&lt;/code&gt; メニューで &lt;code&gt;設定&lt;/code&gt; タブの &lt;code&gt;ウィンドウ拡大縮小&lt;/code&gt; を &lt;code&gt;2倍&lt;/code&gt; に設定する。&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2020/02/13/macbookpro10-xubuntu/2020-02-13_06-59-55_Screenshot_2020-02-13_06-59-30.png"&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;code&gt;/etc/environment&lt;/code&gt; に以下を追記する。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;GDK_SCALE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;QT_AUTO_SCREEN_SCALE_FACTOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;QT_SCALE_FACTOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="emacs"&gt;Emacs&lt;/h4&gt;
&lt;p&gt;フォントサイズが小さいままなので、サイズ指定を倍にすることで暫定対応。&lt;/p&gt;
&lt;p&gt;ただ、画像やモードラインの高さなどが小さいままなので、対応検討中。&lt;/p&gt;
&lt;h4 id="gimp"&gt;GIMP&lt;/h4&gt;
&lt;p&gt;テーマ設定でフォントを大きくするしかない。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cp -r /usr/share/gimp/2.0/themes/Dark ~/.config/GIMP/2.10/themes/MyDark
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;等で元になるテーマをコピーし、以下のような指定を追記(コメントアウトを解除)する。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-conf" data-lang="conf"&gt;gtk-font-name = &amp;#34;Noto Sans Regular 18&amp;#34;
font_name = &amp;#34;Noto Sans Regular 18&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="参考にしたリンク集"&gt;参考にしたリンク集&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://apple.stackexchange.com/questions/304131/no-partition-scheme-option-when-erasing-a-usb-disk-in-macos-high-sierra" target="_blank" rel="noopener"&gt;No partition scheme option when erasing a USB disk in MacOS High Sierra? - Ask Different&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.b-shock.org/2018/03/03/Xubuntu-MacBook-Air/" target="_blank" rel="noopener"&gt;MacBook AirをXubuntuとのデュアルブートにした。 | b-shock. Fortress&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ubuntu.com/tutorials/tutorial-create-a-usb-stick-on-macos" target="_blank" rel="noopener"&gt;Create a bootable USB stick on macOS | Ubuntu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://wiki.archlinux.org/index.php/HiDPI" target="_blank" rel="noopener"&gt;HiDPI - ArchWiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://wiki.archlinux.org/index.php/MacBookPro10,x" target="_blank" rel="noopener"&gt;MacBookPro10,x - ArchWiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://esperas.info/index.php?QBlog-20180312-2" target="_blank" rel="noopener"&gt;macでUSB起動したxubuntuでWiFiを使えた！ - そよ風ブログ - esperas! エスペラントの世界&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://help.ubuntu.com/community/SwapFaq" target="_blank" rel="noopener"&gt;SwapFaq - Community Help Wiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.maketecheasier.com/install-dual-boot-ubuntu-mac/" target="_blank" rel="noopener"&gt;How to Install and Dual-Boot Ubuntu on Mac - Make Tech Easier&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://askubuntu.com/questions/149971/how-do-you-remap-a-key-to-the-caps-lock-key-in-xubuntu" target="_blank" rel="noopener"&gt;How do you remap a key to the Caps Lock key in Xubuntu? - Ask Ubuntu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ubuntuupdates.org/ppa/google%5Fchrome" target="_blank" rel="noopener"&gt;UbuntuUpdates - PPA: Google Chrome&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://askubuntu.com/questions/690512/how-to-enable-natural-scrolling-in-xfce4" target="_blank" rel="noopener"&gt;xubuntu - How to enable natural scrolling in xfce4? - Ask Ubuntu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bugzilla.xfce.org/show%5Fbug.cgi?id=11193" target="_blank" rel="noopener"&gt;11193 – GTK3 apps don&amp;rsquo;t understand natural scrolling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://askubuntu.com/questions/440670/how-do-i-enable-horizontal-scroll-on-lubuntu-desktop" target="_blank" rel="noopener"&gt;touchpad - How do I enable horizontal scroll on lubuntu desktop - Ask Ubuntu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.xfce.org/apps/terminal/dropdown" target="_blank" rel="noopener"&gt;apps:terminal:dropdown [Xfce Docs]​&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://qiita.com/yuji38kwmt/items/cffc3507e0cbd0b76454" target="_blank" rel="noopener"&gt;Xubuntu: `xdg-user-dirs-gtk-update`でユーザーディレクトリが英語名になったけど、なぜか`デスクトップ`ディレクトリが英語にならない - Qiita&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/albertlauncher/albert/issues/793" target="_blank" rel="noopener"&gt;Ubuntu 19.04 package · Issue #793 · albertlauncher/albert&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://unix.stackexchange.com/questions/121395/on-an-apple-keyboard-under-linux-how-do-i-make-the-function-keys-work-without-t" target="_blank" rel="noopener"&gt;On an Apple Keyboard under Linux, how do I make the Function keys work without the fn modifier key? - Unix &amp;amp; Linux Stack Exchange&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Hugo Academic でダーク・ライト両モードに対応した Chroma によるシンタックスハイライト</title><link>https://www.yewton.net/2020/01/24/hugo-academic-dark-light-code-block/</link><pubDate>Fri, 24 Jan 2020 08:37:00 +0900</pubDate><guid>https://www.yewton.net/2020/01/24/hugo-academic-dark-light-code-block/</guid><description>&lt;div class="ox-hugo-toc toc"&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div class="heading"&gt;&amp;#30446;&amp;#27425;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#%e5%89%8d%e6%8f%90"&gt;前提&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#academic-%e6%a8%99%e6%ba%96%e3%81%ae%e3%82%b3%e3%83%bc%e3%83%89%e3%83%8f%e3%82%a4%e3%83%a9%e3%82%a4%e3%83%88%e3%82%92%e7%84%a1%e5%8a%b9%e3%81%ab%e3%81%99%e3%82%8b"&gt;Academic 標準のコードハイライトを無効にする&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#hugo-%e3%81%ae%e3%82%b3%e3%83%bc%e3%83%89%e3%83%8f%e3%82%a4%e3%83%a9%e3%82%a4%e3%83%88%e3%82%92%e6%9c%89%e5%8a%b9%e3%81%ab%e3%81%99%e3%82%8b"&gt;Hugo のコードハイライトを有効にする&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e3%83%80%e3%83%bc%e3%82%af%e3%83%a2%e3%83%bc%e3%83%89%e7%94%a8%e3%81%a8%e3%83%a9%e3%82%a4%e3%83%88%e3%83%a2%e3%83%bc%e3%83%89%e7%94%a8%e3%81%ae-chroma-%e3%82%b9%e3%82%bf%e3%82%a4%e3%83%ab%e3%82%92%e6%b1%ba%e3%82%81%e3%82%8b"&gt;ダークモード用とライトモード用の Chroma スタイルを決める&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#light-%e3%82%b9%e3%82%bf%e3%82%a4%e3%83%ab"&gt;light スタイル&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#dark-%e3%82%b9%e3%82%bf%e3%82%a4%e3%83%ab"&gt;dark スタイル&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#chroma-%e7%94%a8%e3%81%ae-css-%e3%82%92%e7%94%9f%e6%88%90%e3%81%99%e3%82%8b"&gt;Chroma 用の CSS を生成する&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#academic-%e3%81%ae%e3%83%86%e3%83%bc%e3%83%9e%e3%81%a8%e7%ab%b6%e5%90%88%e3%81%97%e3%81%aa%e3%81%84%e3%82%88%e3%81%86%e3%81%ab%e3%81%99%e3%82%8b"&gt;Academic のテーマと競合しないようにする&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;!--endtoc--&gt;
&lt;h2 id="前提"&gt;前提&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://sourcethemes.com/academic/" target="_blank" rel="noopener"&gt;Academic テーマ&lt;/a&gt; のデフォルト設定は &lt;a href="https://sourcethemes.com/academic/docs/writing-markdown-latex/#code-highlighting" target="_blank" rel="noopener"&gt;ドキュメントにもある通り&lt;/a&gt; &lt;a href="https://highlightjs.org/" target="_blank" rel="noopener"&gt;highlight.js&lt;/a&gt; を使ったもので、
この仕組みに乗っておけば基本的には問題ありません。&lt;/p&gt;
&lt;p&gt;ただし highlight.js には一つ問題があって… &lt;strong&gt;EmacsLisp に対応していません&lt;/strong&gt; (Lisp には対応)。
具体的には &lt;code&gt;with-eval-after-load&lt;/code&gt; のような独自のマクロや、
DocString 中のクオテーションといった EmacsLisp 方言には対応出来ません。&lt;/p&gt;
&lt;p&gt;一方、 Hugo 標準の &lt;a href="https://gohugo.io/content-management/syntax-highlighting/" target="_blank" rel="noopener"&gt;Syntax Highlighting&lt;/a&gt; は &lt;a href="https://github.com/alecthomas/chroma" target="_blank" rel="noopener"&gt;Chroma&lt;/a&gt; を使ったもので、
こちらは &lt;strong&gt;EmacsLisp に対応しています&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;(&lt;a href="https://github.com/kaushalmodi/ox-hugo" target="_blank" rel="noopener"&gt;ox-hugo&lt;/a&gt; の作者さんが過去に &lt;a href="https://github.com/alecthomas/chroma/issues/43" target="_blank" rel="noopener"&gt;Issue に挙げてくれていた&lt;/a&gt; 模様…感謝 🙏)&lt;/p&gt;
&lt;p&gt;&lt;a href="https://codepen.io/yewton/pen/RwNvdBz" target="_blank" rel="noopener"&gt;CodePen&lt;/a&gt; と &lt;a href="https://swapoff.org/chroma/playground/" target="_blank" rel="noopener"&gt;Chroma Playground&lt;/a&gt; とでそれぞれの出力結果を比べてみるとよく分かります:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-emacs-lisp" data-lang="emacs-lisp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defvar&lt;/span&gt; &lt;span class="nv"&gt;hoge&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;fuga&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;Doc String 中の &lt;/span&gt;&lt;span class="ss"&gt;`QUOTE&amp;#39;&lt;/span&gt;&lt;span class="s"&gt; はどうなるかな？&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;with-eval-after-load&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;foo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;unless&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;eq&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;EmacsLisp 独自キーワードはどうなるかな？&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="src-block-caption"&gt;
&lt;span class="src-block-number"&gt;ソースコード 1&lt;/span&gt;:
元のコード
&lt;/div&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2020/01/24/hugo-academic-dark-light-code-block/2020-01-24_05-59-12_%E8%B2%BC%E3%82%8A%E4%BB%98%E3%81%91%E3%81%9F%E7%94%BB%E5%83%8F_2020_01_24_5_58.png"
alt="図1: highlight.js w/ GitHub style"&gt;&lt;figcaption&gt;
&lt;p&gt;図1: highlight.js w/ GitHub style&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2020/01/24/hugo-academic-dark-light-code-block/2020-01-24_05-56-58_%E8%B2%BC%E3%82%8A%E4%BB%98%E3%81%91%E3%81%9F%E7%94%BB%E5%83%8F_2020_01_24_5_56.png"
alt="図2: Chroma w/ GitHub style"&gt;&lt;figcaption&gt;
&lt;p&gt;図2: Chroma w/ GitHub style&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;そこで、 &lt;strong&gt;Academic を使いつつ、 Hugo 標準のハイライトの仕組みを使いたい&lt;/strong&gt; というのが動機となります。&lt;/p&gt;
&lt;h2 id="academic-標準のコードハイライトを無効にする"&gt;Academic 標準のコードハイライトを無効にする&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://sourcethemes.com/academic/docs/writing-markdown-latex/#highlighting-options" target="_blank" rel="noopener"&gt;ドキュメント&lt;/a&gt; に書かれている通り、 &lt;code&gt;config.toml&lt;/code&gt; で &lt;code&gt;params.highlight&lt;/code&gt; オプションを無効にする必要があります。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://sourcethemes.com/academic/" target="_blank" rel="noopener"&gt;Academic Kickstart&lt;/a&gt; をベースにしている場合、 &lt;code&gt;params.toml&lt;/code&gt; で以下のように設定します:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Enable source code highlighting? true/false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Documentation: https://sourcethemes.com/academic/docs/writing-markdown-latex/#highlighting-options&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;highlight&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="src-block-caption"&gt;
&lt;span class="src-block-number"&gt;ソースコード 2&lt;/span&gt;:
&lt;code&gt;params.toml&lt;/code&gt;
&lt;/div&gt;
&lt;h2 id="hugo-のコードハイライトを有効にする"&gt;Hugo のコードハイライトを有効にする&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://sourcethemes.com/academic/" target="_blank" rel="noopener"&gt;Academic Kickstart&lt;/a&gt; をベースにしている場合、 &lt;code&gt;config.toml&lt;/code&gt; で以下のように
Hugo のコードハイライトが無効にされていると思います:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;markup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;highlight&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;codeFences&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="c"&gt;# Disable Hugo&amp;#39;s code highlighter as it conflicts with Academic&amp;#39;s highligher.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これを以下のように変更します:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;markup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;highlight&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;codeFences&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;noClasses&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;noClasses = false&lt;/code&gt; としているのは、 &lt;strong&gt;ダーク・ライトの両方のモードに対応させるため&lt;/strong&gt; です。
&lt;code&gt;noClasses&lt;/code&gt; が &lt;code&gt;true&lt;/code&gt; の場合、スタイル指定が HTML 中に埋め込まれます。
これだとモードの変更に追従して動的にスタイルを変更するということが出来ないため、
CSS クラスだけを HTML に埋め込んでもらうようにします。&lt;/p&gt;
&lt;h2 id="ダークモード用とライトモード用の-chroma-スタイルを決める"&gt;ダークモード用とライトモード用の Chroma スタイルを決める&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://xyproto.github.io/splash/docs/" target="_blank" rel="noopener"&gt;Chroma Style Gallery&lt;/a&gt; ギャラリーを参考に、
&lt;strong&gt;ダークモード時に使うスタイルとライトモード時に使うスタイルをそれぞれ決めます&lt;/strong&gt; 。
モードの切り替わりに応じて、シンタックスハイライトのスタイル自体を変更してしまいます。&lt;/p&gt;
&lt;p&gt;選定の際の注意事項として、 &lt;strong&gt;スタイルによって細かいクラス指定に対応していない場合があります&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;具体的には、 EmacsLisp の &lt;code&gt;defvar&lt;/code&gt; などは &lt;code&gt;NameBuiltin&lt;/code&gt; としてパースされ、
&lt;code&gt;.nb&lt;/code&gt; というクラスが指定されるのですが、これが含まれていないスタイルがいくつかあります。&lt;/p&gt;
&lt;p&gt;参考までに、調査した結果を以下に列挙します:&lt;/p&gt;
&lt;h3 id="light-スタイル"&gt;light スタイル&lt;/h3&gt;
&lt;h4 id="namebuiltin-が含まれるもの"&gt;&lt;code&gt;NameBuiltin&lt;/code&gt; が含まれるもの&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/abap.html" target="_blank" rel="noopener"&gt;abap&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/algol.html" target="_blank" rel="noopener"&gt;algol&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/algol%5Fnu.html" target="_blank" rel="noopener"&gt;algol_nu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/arduino.html" target="_blank" rel="noopener"&gt;arduino&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/autumn.html" target="_blank" rel="noopener"&gt;autumn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/colorful.html" target="_blank" rel="noopener"&gt;colorful&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/emacs.html" target="_blank" rel="noopener"&gt;emacs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/friendly.html" target="_blank" rel="noopener"&gt;friendly&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/github.html" target="_blank" rel="noopener"&gt;github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/lovelace.html" target="_blank" rel="noopener"&gt;lovelace&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/manni.html" target="_blank" rel="noopener"&gt;manni&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/murphy.html" target="_blank" rel="noopener"&gt;murphy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/pastie.html" target="_blank" rel="noopener"&gt;pastie&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/perldoc.html" target="_blank" rel="noopener"&gt;perldoc&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/pygments.html" target="_blank" rel="noopener"&gt;pygments&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/rainbow%5Fdash.html" target="_blank" rel="noopener"&gt;dash&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/solarized-light.html" target="_blank" rel="noopener"&gt;light&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/tango.html" target="_blank" rel="noopener"&gt;tango&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/trac.html" target="_blank" rel="noopener"&gt;trac&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/vim.html" target="_blank" rel="noopener"&gt;vim&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/xcode.html" target="_blank" rel="noopener"&gt;xcode&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="namebuiltin-が含まれないもの"&gt;&lt;code&gt;NameBuiltin&lt;/code&gt; が含まれないもの&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/borland.html" target="_blank" rel="noopener"&gt;borland&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/bw.html" target="_blank" rel="noopener"&gt;bw&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/igor.html" target="_blank" rel="noopener"&gt;igor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/monokailight.html" target="_blank" rel="noopener"&gt;monokailight&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/paraiso-light.html" target="_blank" rel="noopener"&gt;light&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/vs.html" target="_blank" rel="noopener"&gt;vs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="dark-スタイル"&gt;dark スタイル&lt;/h3&gt;
&lt;h4 id="namebuiltin-が含まれるもの"&gt;&lt;code&gt;NameBuiltin&lt;/code&gt; が含まれるもの&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/api.html" target="_blank" rel="noopener"&gt;api&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/dracula.html" target="_blank" rel="noopener"&gt;dracula&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/native.html" target="_blank" rel="noopener"&gt;native&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/solarized-dark.html" target="_blank" rel="noopener"&gt;dark&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/solarized-dark256.html" target="_blank" rel="noopener"&gt;dark256&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/swapoff.html" target="_blank" rel="noopener"&gt;swapoff&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="namebuiltin-が含まれないもの"&gt;&lt;code&gt;NameBuiltin&lt;/code&gt; が含まれないもの&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/fruity.html" target="_blank" rel="noopener"&gt;fruity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/monokai.html" target="_blank" rel="noopener"&gt;monokai&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/paraiso-dark.html" target="_blank" rel="noopener"&gt;dark&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xyproto.github.io/splash/docs/rrt.html" target="_blank" rel="noopener"&gt;rrt&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="chroma-用の-css-を生成する"&gt;Chroma 用の CSS を生成する&lt;/h2&gt;
&lt;p&gt;スタイルを決めたら以下のように CSS を生成します。
生成された CSS は標準出力に吐き出されるため、適当なファイルにリダイレクトするか、 &lt;code&gt;pbcopy&lt;/code&gt; 等にパイプしてクリップボードに格納しましょう:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo gen chromastyles --style&lt;span class="o"&gt;=&lt;/span&gt;pygments
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo gen chromastyles --style&lt;span class="o"&gt;=&lt;/span&gt;native
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;この後多少手を加える必要があるので、やりやすいように &lt;a href="https://css2sass.herokuapp.com/" target="_blank" rel="noopener"&gt;CSS 2 SASS/SCSS CONVERTER&lt;/a&gt; 等で SCSS に変換しておくとよいです。&lt;/p&gt;
&lt;h2 id="academic-のテーマと競合しないようにする"&gt;Academic のテーマと競合しないようにする&lt;/h2&gt;
&lt;p&gt;生成した CSS(SCSS) は &lt;a href="https://sourcethemes.com/academic/docs/customization/#customize-style-css" target="_blank" rel="noopener"&gt;Academic のドキュメント&lt;/a&gt; に従い &lt;code&gt;custom.css&lt;/code&gt; に追加します。&lt;/p&gt;
&lt;p&gt;ただし、Academic には標準のハイライトのためのスタイル指定があるため、
Chroma が生成したスタイル指定をそのまま組込むと若干コンフリクトします。&lt;/p&gt;
&lt;p&gt;そこで、多少手を加えてやります。&lt;/p&gt;
&lt;p&gt;まずライトモード時のスタイルについては、
&lt;code&gt;background-color&lt;/code&gt; や &lt;code&gt;color&lt;/code&gt; が指定されていない場合があるため( &lt;code&gt;pygments&lt;/code&gt; 等)、
&lt;a href="https://swapoff.org/chroma/playground/" target="_blank" rel="noopener"&gt;Chroma Playground&lt;/a&gt; の出力結果を参考にしてスタイル指定を追加します。&lt;/p&gt;
&lt;p&gt;また、 Academic 組込みの &lt;code&gt;code&lt;/code&gt; へのスタイル指定より優先度が高くなるように、
セレクタを &lt;code&gt;pre.chroma, .chroma code&lt;/code&gt; とします。&lt;/p&gt;
&lt;p&gt;最終的に以下のようになります:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-scss" data-lang="scss"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;pre&lt;/span&gt;&lt;span class="nc"&gt;.chroma&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;.chroma&lt;/span&gt; &lt;span class="nt"&gt;code&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;background-color&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#f5f5f5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#4a4a4a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;次にダークモード時のスタイルについては、
基本的に &lt;code&gt;background-color&lt;/code&gt; や &lt;code&gt;color&lt;/code&gt; も指定されていると思うので、
セレクタのみ &lt;code&gt;.dark pre.chroma, .dark .chroma code&lt;/code&gt; としてあげます。&lt;/p&gt;
&lt;p&gt;以上で、 &lt;strong&gt;Hugo Academic を使いつつ、 Chroma でシンタックスハイライト&lt;/strong&gt; が実現出来ました。&lt;/p&gt;</description></item><item><title>GitHub Pages + Cloudflare から Netlify に移行した</title><link>https://www.yewton.net/2020/01/13/hugo-netlify/</link><pubDate>Mon, 13 Jan 2020 00:00:00 +0000</pubDate><guid>https://www.yewton.net/2020/01/13/hugo-netlify/</guid><description>&lt;p&gt;&lt;a href="https://www.yewton.net/2016/02/02/blog-with-hugo/"&gt;この記事にあるとおり&lt;/a&gt; 、当初このサイトは &lt;a href="https://pages.github.com/" target="_blank" rel="noopener"&gt;GitHub Pages&lt;/a&gt; でホストされ、
&lt;a href="https://www.cloudflare.com/" target="_blank" rel="noopener"&gt;Cloudflare CDN&lt;/a&gt; を利用して配信していた。&lt;/p&gt;
&lt;p&gt;だが先日 &lt;a href="https://www.yewton.net/2020/01/06/made-with-academic/"&gt;テーマを変えた&lt;/a&gt; ときに、既に使われていないリソースがそのまま残ってしまっていることに気がついた。
単純に &lt;code&gt;/public&lt;/code&gt; 以下を &lt;code&gt;git add -a&lt;/code&gt; しているだけなので、明示的に消さなければ反映されなくて当然だった。&lt;/p&gt;
&lt;p&gt;デプロイスクリプトを見直してもよかったが、 &lt;a href="https://gohugo.io/" target="_blank" rel="noopener"&gt;Hugo&lt;/a&gt; 自体が &lt;a href="https://www.netlify.com/" target="_blank" rel="noopener"&gt;Netlify&lt;/a&gt; でホストされているし、
&lt;a href="https://gohugo.io/hosting-and-deployment/hosting-on-netlify/" target="_blank" rel="noopener"&gt;Netlify でホストするときの公式ドキュメントも用意されている&lt;/a&gt; し、
&lt;a href="https://docs.netlify.com/site-deploys/post-processing/#post-processing-features" target="_blank" rel="noopener"&gt;アセットの最適化機能&lt;/a&gt; とかもついてくるし、何より &lt;a href="https://www.netlify.com/pricing/" target="_blank" rel="noopener"&gt;無料だし&lt;/a&gt; 、
ということで、移行することを決めた。&lt;/p&gt;
&lt;div class="ox-hugo-toc toc"&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div class="heading"&gt;&amp;#30446;&amp;#27425;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#%e3%83%87%e3%83%97%e3%83%ad%e3%82%a4%e6%89%8b%e9%a0%86"&gt;デプロイ手順&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e3%83%89%e3%83%a1%e3%82%a4%e3%83%b3%e7%a7%bb%e8%a1%8c%e6%89%8b%e9%a0%86"&gt;ドメイン移行手順&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#github-pages-%e3%81%a7%e6%8f%90%e4%be%9b%e3%81%97%e3%81%a6%e3%81%84%e3%81%9f%e3%81%9d%e3%81%ae%e4%bb%96%e3%81%ae%e3%83%aa%e3%83%9d%e3%82%b8%e3%83%88%e3%83%aa%e3%81%ae%e3%83%aa%e3%83%80%e3%82%a4%e3%83%ac%e3%82%af%e3%83%88%e8%a8%ad%e5%ae%9a%e6%89%8b%e9%a0%86"&gt;GitHub Pages で提供していたその他のリポジトリのリダイレクト設定手順&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#%e3%81%9d%e3%81%ae%e5%be%8c"&gt;その後&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;!--endtoc--&gt;
&lt;h2 id="デプロイ手順"&gt;デプロイ手順&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://gohugo.io/hosting-and-deployment/hosting-on-netlify/" target="_blank" rel="noopener"&gt;公式ドキュメント&lt;/a&gt; を超ざっくり要約すると、&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://app.netlify.com/" target="_blank" rel="noopener"&gt;Netlify でアカウント作成&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gohugo.io/hosting-and-deployment/hosting-on-netlify/#configure-hugo-version-in-netlify" target="_blank" rel="noopener"&gt;&lt;code&gt;netlify.toml&lt;/code&gt;&lt;/a&gt; をドキュメントを参考に配置&lt;/li&gt;
&lt;li&gt;連携する GitHub リポジトリを選択&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Deploy site&lt;/code&gt; ボタンをポチる&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;以上。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;これだけで &lt;code&gt;hoge.netlify.com&lt;/code&gt; でアクセス出来るようになる。いい時代になった。&lt;/p&gt;
&lt;h2 id="ドメイン移行手順"&gt;ドメイン移行手順&lt;/h2&gt;
&lt;p&gt;ただドメインも移行する場合はもう一手間必要で、&lt;a href="https://docs.netlify.com/domains-https/custom-domains/configure-external-dns/" target="_blank" rel="noopener"&gt;Netlify の公式ドキュメント&lt;/a&gt; に従って
DNS レコードの設定をする必要がある。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.cloudflare.com/" target="_blank" rel="noopener"&gt;Cloudflare&lt;/a&gt; の場合は、以下のように Cloudflare のダッシュボードで、
各ドメインが Netlify への &lt;code&gt;CNAME&lt;/code&gt; となるように設定する。&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2020/01/13/hugo-netlify/2020-01-13_15-37-38_cloudflare.png"&gt;
&lt;/figure&gt;
&lt;p&gt;このとき、 &lt;strong&gt;&lt;code&gt;Proxy status&lt;/code&gt; が &lt;code&gt;DNS only&lt;/code&gt; となるように&lt;/strong&gt;
(雲のアイコンがオレンジではなくグレーになるように) 設定する必要がある。&lt;/p&gt;
&lt;p&gt;さもないと、 Cloudflare の CDN 機能が間に挟まってしまい、 Netlify 側から認識されない。&lt;/p&gt;
&lt;p&gt;なお、 &lt;strong&gt;&lt;code&gt;DNS only&lt;/code&gt; にした時点で Cloudflare が発行した SSL 証明書は無効になる&lt;/strong&gt; 。
そのため、ここからなるべく早く &lt;a href="https://docs.netlify.com/domains-https/https-ssl/#certificate-service-types" target="_blank" rel="noopener"&gt;Netlify 側の SSL 証明書の設定&lt;/a&gt; をした方がいい。&lt;/p&gt;
&lt;p&gt;当サイトの場合は設定してから1時間もしない内に SSL 証明書が有効になっていた。&lt;/p&gt;
&lt;h2 id="github-pages-で提供していたその他のリポジトリのリダイレクト設定手順"&gt;GitHub Pages で提供していたその他のリポジトリのリダイレクト設定手順&lt;/h2&gt;
&lt;p&gt;サイトだけなら以上で万事完了なのだけれど、 GitHub Pages を利用していた場合の注意点として、
&lt;code&gt;github.io&lt;/code&gt; リポジトリで &lt;code&gt;CNAME&lt;/code&gt; を設定していた場合、それ以外で Pages 機能を利用しているリポジトリも同様のドメインでアクセスされるようになっている。
つまり、 &lt;code&gt;github.io&lt;/code&gt; を Netlify へ向けた時点で、 &lt;strong&gt;それ以外のリポジトリが全てリンク切れとなる。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;そのため、適切にリダイレクトするようにしなければならない。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://docs.netlify.com/routing/redirects/" target="_blank" rel="noopener"&gt;Netlify の公式ドキュメント&lt;/a&gt; に従ってやればいい…と思ったのだけれど、
原因は不明だが &lt;strong&gt;&lt;code&gt;netlify.toml&lt;/code&gt; で設定しようとしても反映されなかった&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;最終的な &lt;code&gt;_redirects&lt;/code&gt; ファイルの内容は以下のようになった:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;https://yewton-net.netlify.com/* https://www.yewton.net/:splat 301!
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/swagger-top-down-playground/* https://yewton.github.io/swagger-top-down-playground/:splat 301!
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/dockerfiles/* https://yewton.github.io/dockerfiles/:splat 301!
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/kafka-doc-ja/* https://yewton.github.io/kafka-doc-ja/:splat 301!
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="その後"&gt;その後&lt;/h2&gt;
&lt;p&gt;移行ついでに &lt;a href="https://developer.okta.com/blog/2019/04/11/site-security-cloudflare-netlify" target="_blank" rel="noopener"&gt;How to Configure Better Web Site Security with Cloudflare and Netlify | Okta Developer&lt;/a&gt; を参考に
&lt;a href="https://securityheaders.com/" target="_blank" rel="noopener"&gt;Security Headers&lt;/a&gt; や &lt;a href="https://www.ssllabs.com/ssltest/index.html" target="_blank" rel="noopener"&gt;SSL Server Test&lt;/a&gt; で高評価になるように設定を見直したりなどした。&lt;/p&gt;
&lt;p&gt;ただこれはあんまり理解しないで書かれてる通りやっただけなところがあるので、いつか改めて記事にしたい。&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2020/01/13/hugo-netlify/2020-01-13_15-12-54_securityheaders.png"&gt;
&lt;/figure&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2020/01/13/hugo-netlify/2020-01-13_15-15-03_qualys.png"&gt;
&lt;/figure&gt;</description></item><item><title>無料でいい感じのバナー用背景素材をダウンロード出来るフリー画像サービス 3 選</title><link>https://www.yewton.net/2020/01/13/unsplash-pexels-pixabay/</link><pubDate>Mon, 13 Jan 2020 00:00:00 +0000</pubDate><guid>https://www.yewton.net/2020/01/13/unsplash-pexels-pixabay/</guid><description>&lt;p&gt;記事のバナー、アイキャッチ画像(&lt;a href="https://sourcethemes.com/academic/" target="_blank" rel="noopener"&gt;Academic&lt;/a&gt; 的には &lt;a href="https://sourcethemes.com/academic/docs/managing-content/#featured-image" target="_blank" rel="noopener"&gt;Featured image&lt;/a&gt;)があると書く時のテンションが上がるので、
出来るだけ設定するようにしたい。&lt;/p&gt;
&lt;p&gt;でも出来るだけ手間はかけたくない…、そんな時に使っているサービスを順不同で挙げる。&lt;/p&gt;
&lt;p&gt;なお、いずれのサービスにおいても、 &lt;code&gt;geometric&lt;/code&gt; (幾何学模様)や
&lt;code&gt;abstract&lt;/code&gt; (抽象的)、あるいは &lt;code&gt;network&lt;/code&gt; や &lt;code&gt;programming&lt;/code&gt; といったワードで検索すると、
いわゆる &lt;em&gt;いい感じ&lt;/em&gt; な画像がヒットする。&lt;/p&gt;
&lt;h2 id="unsplash"&gt;Unsplash&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.notion.so/" target="_blank" rel="noopener"&gt;Notion&lt;/a&gt; のカバーイメージ選択欄にあったので存在を知った。&lt;/p&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;
&lt;img alt=""
srcset="https://www.yewton.net/2020/01/13/unsplash-pexels-pixabay/2020-01-13_11-43-22_ash-edmonds-0aWZdK8nK2I-unsplash_hu_fcdb3c406f0ce966.webp 320w, https://www.yewton.net/2020/01/13/unsplash-pexels-pixabay/2020-01-13_11-43-22_ash-edmonds-0aWZdK8nK2I-unsplash_hu_5711d88f829f71c.webp 480w, https://www.yewton.net/2020/01/13/unsplash-pexels-pixabay/2020-01-13_11-43-22_ash-edmonds-0aWZdK8nK2I-unsplash_hu_c711cc14c11c64e4.webp 760w"
sizes="(max-width: 480px) 100vw, (max-width: 768px) 90vw, (max-width: 1024px) 80vw, 760px"
src="https://www.yewton.net/2020/01/13/unsplash-pexels-pixabay/2020-01-13_11-43-22_ash-edmonds-0aWZdK8nK2I-unsplash_hu_fcdb3c406f0ce966.webp"
width="760"
height="507"
loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;p class="featured-image-credit"&gt;
Image by
&lt;a style="background-color:black;color:white;text-decoration:none;padding:4px 6px;font-family:-apple-system, BlinkMacSystemFont, &amp;quot;San Francisco&amp;quot;, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, Ubuntu, Roboto, Noto, &amp;quot;Segoe UI&amp;quot;, Arial, sans-serif;font-size:12px;font-weight:bold;line-height:1.2;display:inline-block;border-radius:3px" href="https://unsplash.com/@badashphotos?utm_medium=referral&amp;amp;utm_campaign=photographer-credit&amp;amp;utm_content=creditBadge" target="_blank" rel="noopener noreferrer" title="Download free do whatever you want high-resolution photos from Ash Edmonds"&gt;
&lt;span style="display:inline-block;padding:2px 3px"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" style="height:12px;width:auto;position:relative;vertical-align:middle;top:-2px;fill:white" viewBox="0 0 32 32"&gt;
&lt;title&gt;unsplash-logo&lt;/title&gt;
&lt;path d="M10 9V0h12v9H10zm12 5h10v18H0V14h10v9h12v-9z"&gt;&lt;/path&gt;
&lt;/svg&gt;
&lt;/span&gt;
&lt;span style="display:inline-block;padding:2px 3px"&gt;Ash Edmonds&lt;/span&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;&lt;a href="https://unsplash.com/license" target="_blank" rel="noopener"&gt;License | Unsplash&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://help.unsplash.com/en/articles/2612315-can-i-use-unsplash-photos-for-personal-or-commercial-projects" target="_blank" rel="noopener"&gt;FAQ ページ&lt;/a&gt; より引用:&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;The photos on Unsplash are free to use and can be used for most commercial, personal projects, and for editorial use.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="pexels"&gt;Pexels&lt;/h2&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;
&lt;img alt=""
srcset="https://www.yewton.net/2020/01/13/unsplash-pexels-pixabay/2020-01-13_11-46-07_abstract-architecture-building-exterior-geometric-593158_hu_689ee0acf74436f5.webp 320w, https://www.yewton.net/2020/01/13/unsplash-pexels-pixabay/2020-01-13_11-46-07_abstract-architecture-building-exterior-geometric-593158_hu_7f22a47b75521181.webp 480w, https://www.yewton.net/2020/01/13/unsplash-pexels-pixabay/2020-01-13_11-46-07_abstract-architecture-building-exterior-geometric-593158_hu_9e12aae368ab8296.webp 640w"
sizes="(max-width: 480px) 100vw, (max-width: 768px) 90vw, (max-width: 1024px) 80vw, 760px"
src="https://www.yewton.net/2020/01/13/unsplash-pexels-pixabay/2020-01-13_11-46-07_abstract-architecture-building-exterior-geometric-593158_hu_689ee0acf74436f5.webp"
width="640"
height="457"
loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;p class="featured-image-credit"&gt;
&lt;span style="display:inline-block;padding:2px 3px"&gt;
Photo by by &lt;a href="https://www.pexels.com/@scottwebb" target="_blank"&gt;Webb from Pexels&lt;/a&gt;
&lt;/span&gt;
&lt;span style="display:inline-block;padding:2px 3px"&gt;
&lt;a href="https://www.pexels.com/@scottwebb" target="_blank"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" width="32px" height="32px" viewBox="0 0 32 32"&gt;
&lt;path d="M2 0h28a2 2 0 0 1 2 2v28a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2z" fill="#05A081"&gt;&lt;/path&gt;
&lt;path d="M13 21h3.863v-3.752h1.167a3.124 3.124 0 1 0 0-6.248H13v10zm5.863 2H11V9h7.03a5.124 5.124 0 0 1 .833 10.18V23z" fill="#fff"&gt;&lt;/path&gt;
&lt;/svg&gt;
&lt;/a&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.pexels.com/photo-license/" target="_blank" rel="noopener"&gt;License of our free stock photos - Pexels&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.pexels.com/ja-jp/faq/" target="_blank" rel="noopener"&gt;FAQ ページ&lt;/a&gt; より引用:&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;Yes, all photos and videos are free for commercial use. You can use them on your commercial website, blog, product or anywhere else.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!--quoteend--&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;すべての写真や動画は、商業コンテンツの一部として無料で利用できます。商業用のWebサイト、ブログ、製品、その他どんな場所にでも利用可能です。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="pixabay"&gt;Pixabay&lt;/h2&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;
&lt;img alt=""
srcset="https://www.yewton.net/2020/01/13/unsplash-pexels-pixabay/2020-01-23_04-30-34_social-3064515_1280_hu_69b9922518696bdd.webp 320w, https://www.yewton.net/2020/01/13/unsplash-pexels-pixabay/2020-01-23_04-30-34_social-3064515_1280_hu_c2df98f6caf3ec54.webp 480w, https://www.yewton.net/2020/01/13/unsplash-pexels-pixabay/2020-01-23_04-30-34_social-3064515_1280_hu_fd666aec2ff40892.webp 760w"
sizes="(max-width: 480px) 100vw, (max-width: 768px) 90vw, (max-width: 1024px) 80vw, 760px"
src="https://www.yewton.net/2020/01/13/unsplash-pexels-pixabay/2020-01-23_04-30-34_social-3064515_1280_hu_69b9922518696bdd.webp"
width="760"
height="506"
loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;p class="featured-image-credit"&gt;
&lt;span style="display:inline-block;padding:2px 3px"&gt;
Image by &lt;a href="https://pixabay.com/users/geralt-9301/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=3064515"&gt;Gerd Altmann&lt;/a&gt; from &lt;a href="https://pixabay.com/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=3064515"&gt;Pixabay&lt;/a&gt;
&lt;/span&gt;
&lt;span style="display:inline-block;padding:2px 3px"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" height="50" width="50" version="1.1" viewBox="0 0 500 500"&gt;
&lt;g transform="translate(-507.42999,175.07001)"&gt;
&lt;rect height="500" width="500" y="-175.07" x="507.43" fill="#222"/&gt;
&lt;g fill="#FFF" transform="matrix(2.7777778,0,0,2.7777778,-2096.4989,0.29221019)"&gt;
&lt;path d="m993.33-7.7954c-2.671,0-4.8365-2.1665-4.8365-4.8392h-16.569c0,2.6727-2.1651,4.8392-4.8363,4.8392h-4.4254v51.484h84.798v-51.483h-54.065zm-4.83,15.24h-16.571v-7.2076h16.569v7.2076zm29.124,28.522c-9.8169,0-17.804-7.9906-17.804-17.813,0-9.8226,7.987-17.402,17.804-17.402,9.8171,0,17.804,7.5795,17.804,17.402,0,9.8226-7.9865,17.813-17.804,17.813zm9.571-17.813c0,5.28-4.2937,9.576-9.5707,9.576-5.2772,0-9.5708-4.2963-9.5708-9.576,0-5.2806,4.2936-9.576,9.5708-9.576,5.277,0,9.5707,4.2957,9.5707,9.576zm66.262-29.941-21.421,55.346-17.241-6.6808v-9.4327l12.218,4.7345,15.073-38.942-56.483-21.887-5.2351,13.525h-9.426l9.6383-24.901,72.876,28.239z"/&gt;
&lt;g style="letter-spacing:0px;word-spacing:0px;" font-family="VomZom" font-size="27.43096924px" line-height="125%" font-stretch="normal" font-variant="normal" font-weight="normal" font-style="normal"&gt;
&lt;path d="m972.14,64.921c-2.7039,0.06735-4.9506,0.99582-6.7402,2.7854s-2.7181,4.0364-2.7854,6.7402v17.223h3.7847v-7.6545h5.7409c2.7056-0.0691,4.9595-1.0047,6.7615-2.8067s2.7375-4.0558,2.8067-6.7615c-0.0691-2.7039-1.0047-4.9506-2.8067-6.7402s-4.0558-2.718-6.7615-2.7854zm-5.7409,15.309,0-5.7834c0.0399-1.6346,0.59801-2.99,1.6744-4.0665,1.0764-1.0764,2.4319-1.6345,4.0665-1.6744,1.6549,0.03988,3.0228,0.59802,4.1037,1.6744,1.0808,1.0764,1.6407,2.4319,1.6797,4.0665-0.039,1.6549-0.59891,3.0228-1.6797,4.1037-1.0809,1.0809-2.4488,1.6408-4.1037,1.6797z"/&gt;
&lt;path d="m984.13,83.93,3.7422,0,0-19.094-3.7422,0z"/&gt;
&lt;path d="m1004.9,83.973-4.9073-6.2277-4.4076,6.2277-5.282,0,7.3341-9.7788-6.7452-9.3327,5.1214,0,4.0329,5.8352,4.4968-5.8352,5.0857,0-7.3341,9.3327,8.0122,9.7788z"/&gt;
&lt;path d="m1020,64.836c-2.78,0.01392-5.5411,1.2356-7.3217,3.389-2.5173,2.889-2.9277,7.3319-1.1016,10.68,1.503,2.8167,4.4818,4.7722,7.6742,4.9822,2.0115,0.08973,4.028,0.02048,6.0416,0.04228h4.2331c-0.01-3.315,0.02-6.6309-0.015-9.9454-0.098-2.8431-1.5228-5.5984-3.8252-7.2788-1.6236-1.2335-3.6602-1.8331-5.6853-1.8696zm0,15.309c-2.4155,0.03477-4.7585-1.5866-5.4781-3.9086-0.8301-2.3925,0.086-5.2767,2.2388-6.6514,2.3653-1.6093,5.9042-1.1463,7.6851,1.1269,1.09,1.2527,1.3722,2.9584,1.2951,4.5678v4.865h-5.7z"/&gt;
&lt;path d="m1035.6,64.921v-7.6545h-3.7848c0.01,5.8108-0.012,11.622,0.01,17.432,0.054,3.9898,2.8702,7.7511,6.7059,8.8726,3.6906,1.1933,8.0347-0.12452,10.369-3.2412,2.8592-3.5647,2.6169-9.1977-0.6105-12.455-1.9534-2.1419-4.9109-3.0977-7.76-2.9545h-4.9289zm5.7834,15.309c-2.6131,0.04941-5.1132-1.8749-5.6269-4.4552-0.2827-1.5643-0.1078-3.1645-0.1565-4.7461v-2.323c2.1274,0.02223,4.2582-0.04689,6.3833,0.03925,2.6883,0.20268,4.9782,2.5587,5.1161,5.2493,0.2744,2.6972-1.6024,5.4384-4.2654,6.0466-0.4742,0.1185-0.9623,0.1776-1.4506,0.18916z"/&gt;
&lt;path d="m1062.7,64.836c-2.7799,0.01394-5.5411,1.2356-7.3217,3.389-2.5172,2.889-2.9276,7.3319-1.1015,10.68,1.5029,2.8167,4.4818,4.7722,7.6742,4.9822,2.0115,0.08973,4.0279,0.02048,6.0415,0.04228h4.2332c-0.01-3.315,0.02-6.6309-0.015-9.9454-0.098-2.8431-1.5228-5.5984-3.8252-7.2788-1.6236-1.2335-3.6602-1.8331-5.6854-1.8696zm0,15.309c-2.4155,0.03475-4.7585-1.5866-5.478-3.9086-0.8301-2.3925,0.086-5.2767,2.2388-6.6514,2.3653-1.6093,5.9042-1.1463,7.6851,1.1269,1.09,1.2527,1.3721,2.9584,1.295,4.5678v4.865h-5.7z"/&gt;
&lt;path d="m1089.9,64.879c-0.016,3.3276,0.032,6.6571-0.025,9.9835-0.1308,2.7-2.413,5.0836-5.1161,5.2865-2.7002,0.34612-5.4922-1.4815-6.1585-4.1395-0.3846-1.5788-0.1677-3.2172-0.2248-4.8256v-6.305h-3.7848c0.014,3.3424-0.029,6.6862,0.023,10.028,0.1465,4.1428,3.3074,7.9466,7.3694,8.8022,2.7164,0.66144,5.7202,0.05068,7.9166-1.6922,0.066,2.6174-1.8415,5.1442-4.428,5.6694-1.0594,0.24194-2.1504,0.13118-3.2266,0.15651v3.7847c2.1224,0.04087,4.3304-0.0016,6.2465-1.0395,3.2212-1.6055,5.2812-5.14,5.1928-8.7259v-16.983c-1.2616,0.000002-2.5231,0.000003-3.7847,0.000005z"/&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/svg&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;&lt;a href="https://pixabay.com/service/license/" target="_blank" rel="noopener"&gt;Pixabay License&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://pixabay.com/service/faq/" target="_blank" rel="noopener"&gt;FAQ ページ&lt;/a&gt; より引用:&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;You can copy, modify, distribute, and use the images, even for commercial purposes, all without asking for permission or giving credits to the artist. However, depicted content may still be protected by trademarks, publicity or privacy rights.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!--quoteend--&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;これらの画像は、商用、非商用を問わず、コピー、改変、再配布することができます。利用に関する許諾や使用料の支払いは必要ありません。しかし、画像の中には商標やパブリシティ権、プライバシー権などに基づき保護されているものが含まれます。&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>Lenovo Tab M8 が案外良かった</title><link>https://www.yewton.net/2020/01/11/lenovo-tab-m8/</link><pubDate>Sat, 11 Jan 2020 00:00:00 +0000</pubDate><guid>https://www.yewton.net/2020/01/11/lenovo-tab-m8/</guid><description>&lt;p class="mylastmod"&gt; 27, 2021 最終更新&lt;/p&gt;
&lt;p&gt;さすがにもう &lt;a href="https://www.yewton.net/2017/04/09/grouper-beanstalk/"&gt;Nexus 7 2012&lt;/a&gt; でやっていくのはしんどくなってきたので、手軽なタブレットを探していたら、
2019 年の 11 月に Lenovo から &lt;a href="https://hb.afl.rakuten.co.jp/hgc/1a0d625b.bdb81d38.1a0d625c.bf0332b2/?pc=https%3A%2F%2Fitem.rakuten.co.jp%2Fbiccamera%2F4580550700484%2F&amp;amp;m=http%3A%2F%2Fm.rakuten.co.jp%2Fbiccamera%2Fi%2F12780179%2F&amp;amp;link%5Ftype=hybrid%5Furl&amp;amp;ut=eyJwYWdlIjoiaXRlbSIsInR5cGUiOiJoeWJyaWRfdXJsIiwic2l6ZSI6IjI0MHgyNDAiLCJuYW0iOjEsIm5hbXAiOiJyaWdodCIsImNvbSI6MSwiY29tcCI6ImRvd24iLCJwcmljZSI6MCwiYm9yIjoxLCJjb2wiOjEsImJidG4iOjEsInByb2QiOjB9" target="_blank" rel="noopener"&gt;Lenovo Tab M8 (ZA5G0084JP)&lt;/a&gt; が発売されていたのを知った。&lt;/p&gt;
&lt;p&gt;2 万を切る価格で、 Android 9 、クアッドコアでメモリは 2 GB 、ディスプレイは 8.0 型ワイド IPS パネル (1280x800ドット)と、そこそこ使えそうなスペック。&lt;/p&gt;
&lt;p&gt;ただストレージは 16GB と心許ないので、 microSD による拡張は必須(最大128GBまで)。自分はたまたま持ってた &lt;a href="https://amzn.to/2QJFCF8" target="_blank" rel="noopener"&gt;SanDisk 製の microSDXC カード&lt;/a&gt; を使っている。アプリ最適化対応じゃないので少々もっさりはするけれど、使えない程ではない。&lt;/p&gt;
&lt;p&gt;電子書籍が読めればいいやというくらいの気持ちで購入したのだけれど、意外なことに &lt;strong&gt;音がいい&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;確かに &lt;a href="https://www.lenovo.com/jp/ja/tablets/android-tablets/tab-series/Lenovo-Tab-M8-2nd-Gen-HD/p/ZZITZTATB58" target="_blank" rel="noopener"&gt;公式サイト&lt;/a&gt; には以下のようにあるけれども、正直期待していなかった。&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;鮮やかでシームレスな映像表示を実現する狭額縁による高画面占有率83％のマルチタッチ対応の8.0型ワイドIPSパネル、ドルビーオーディオ対応のオーディオ機能を搭載。鮮明な映像と臨場感のあるサウンドで、お気に入りのビデオのストリーミングやモバイルゲームを楽しめます。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="https://amzn.to/2T4dbTB" target="_blank" rel="noopener"&gt;Sony WH-XB900N&lt;/a&gt; を Bluetooth 接続で聴いているが、手持ちの Pixel 3 XL に繋いだ場合と比較すると結構違う。そんなに大した耳を持ってるわけじゃないけど、低音がすごく心地良く響く感じ。&lt;/p&gt;
&lt;p&gt;イコライザは以下のように設定している:&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2020/01/11/lenovo-tab-m8/2020-01-09_06-10-17_Screenshot_2020-01-08-01-02-47-757.jpeg"
alt="図1: Dolby Audio のイコライザ設定"&gt;&lt;figcaption&gt;
&lt;p&gt;図1: Dolby Audio のイコライザ設定&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;意外と音が良いので色々やりたくなってしまい、年末にセールしていた &lt;a href="https://play.google.com/store/apps/details?id=com.square%5Fenix.android%5Fgoogleplay.FFT%5Fjp2&amp;amp;hl=ja" target="_blank" rel="noopener"&gt;FINAL FANTASY TACTICS 獅子戦争&lt;/a&gt; を買ってしまった。割と快適に動くので読書よりもゲームをやってしまう…。&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2020/01/11/lenovo-tab-m8/2020-01-09_08-36-49_Screenshot%20%282020_01_08%206_12_13%29.jpg"
alt="図2: いつまでもゼクラス砂漠から出られない一行"&gt;&lt;figcaption&gt;
&lt;p&gt;図2: いつまでもゼクラス砂漠から出られない一行&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;そんなわけで案外良かった Lenovo Tab M8 だがおかしな挙動もあり、まず &lt;strong&gt;再起動すると必ず「SDカードが見つからない」旨の通知が表示される&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;そして、 &lt;strong&gt;スクリーンショットの動作が安定しない&lt;/strong&gt; 。上記の現象もスクリーンショットが保存できなかった。&lt;/p&gt;
&lt;p&gt;一番うっとうしいのが、 &lt;strong&gt;横画面になる度に Lenovo Launcher が停止する&lt;/strong&gt; こと。停止する度にダイアログが出るので邪魔。とはいえ「アプリを閉じる」を選択してしまえば以降差し支えなく使用は可能。&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.yewton.net/2020/01/11/lenovo-tab-m8/2020-01-08_06-36-20_Screenshot_2020-01-08-01-02-37-802.jpeg"
alt="図3: 横画面になる度に表示されるうっとうしいダイアログ"&gt;&lt;figcaption&gt;
&lt;p&gt;図3: 横画面になる度に表示されるうっとうしいダイアログ&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;div class="callout flex px-4 py-3 mb-6 rounded-md border-l-4 bg-blue-100 dark:bg-blue-900 border-blue-500"
data-callout="note"
data-callout-metadata=""&gt;
&lt;span class="callout-icon pr-3 pt-1 text-blue-600 dark:text-blue-300"&gt;
&lt;svg height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&gt;&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="m16.862 4.487l1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8l.8-2.685a4.5 4.5 0 0 1 1.13-1.897zm0 0L19.5 7.125"/&gt;&lt;/svg&gt;
&lt;/span&gt;
&lt;div class="callout-content dark:text-neutral-300"&gt;
&lt;div class="callout-title font-semibold mb-1"&gt;Note&lt;/div&gt;
&lt;div class="callout-body"&gt;&lt;p&gt;2020年1月20日に配信されたアップデートを適用したところ、少なくとも &lt;code&gt;Lenovo Launcher が停止しました&lt;/code&gt; のダイアログは出なくなっていた。&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class="featured-image-credit"&gt;
Featured image background by
&lt;a style="background-color:black;color:white;text-decoration:none;padding:4px 6px;font-family:-apple-system, BlinkMacSystemFont, &amp;quot;San Francisco&amp;quot;, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, Ubuntu, Roboto, Noto, &amp;quot;Segoe UI&amp;quot;, Arial, sans-serif;font-size:12px;font-weight:bold;line-height:1.2;display:inline-block;border-radius:3px" href="https://unsplash.com/@%20estherrj?utm_medium=referral&amp;amp;utm_campaign=photographer-credit&amp;amp;utm_content=creditBadge" target="_blank" rel="noopener noreferrer" title="Download free do whatever you want high-resolution photos from Esther Jiao"&gt;
&lt;span style="display:inline-block;padding:2px 3px"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" style="height:12px;width:auto;position:relative;vertical-align:middle;top:-2px;fill:white" viewBox="0 0 32 32"&gt;
&lt;title&gt;unsplash-logo&lt;/title&gt;
&lt;path d="M10 9V0h12v9H10zm12 5h10v18H0V14h10v9h12v-9z"&gt;&lt;/path&gt;
&lt;/svg&gt;
&lt;/span&gt;
&lt;span style="display:inline-block;padding:2px 3px"&gt; Esther Jiao&lt;/span&gt;
&lt;/a&gt;
&lt;/p&gt;</description></item><item><title>org-mode に Chrome で開いてるページへのリンクを貼りたい</title><link>https://www.yewton.net/2020/01/10/org-mode-web-link/</link><pubDate>Fri, 10 Jan 2020 00:00:00 +0000</pubDate><guid>https://www.yewton.net/2020/01/10/org-mode-web-link/</guid><description>&lt;p&gt;&lt;code&gt;org-mode&lt;/code&gt; のリンクマークアップはちょっと特殊で、エスケープの仕様も独特です。&lt;/p&gt;
&lt;p&gt;また、 &lt;a href="https://code.orgmode.org/bzg/org-mode/src/release%5F9.3/etc/ORG-NEWS" target="_blank" rel="noopener"&gt;2019年の12月にリリースされたバージョン 9.3 で後方互換性の無い仕様変更が入る&lt;/a&gt; ということも有りました。&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;&lt;strong&gt;Version 9.3&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Incompatible changes&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Change bracket link escaping syntax
Org used to percent-encode sensitive characters in the URI part of the bracket links.&lt;/p&gt;
&lt;p&gt;Now, escaping mechanism uses the usual backslash character, according to the following rules, applied in order:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-emacs-lisp" data-lang="emacs-lisp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;org-link-unescape&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;link&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;Remove escaping backslash characters from string LINK.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;replace-regexp-in-string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;rx&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;group&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;one-or-more&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;\\&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;or&lt;/span&gt; &lt;span class="nv"&gt;string-end&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;any&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;[]&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;make-string&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;match-end&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;match-beginning&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="sc"&gt;?\\&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;link&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="src-block-caption"&gt;
&lt;span class="src-block-number"&gt;ソースコード 1&lt;/span&gt;:
(参考) &lt;code&gt;org-mode&lt;/code&gt; 9.3 でのエスケープ実装
&lt;/div&gt;
&lt;p&gt;こういう背景もあり、 &lt;code&gt;org-mode&lt;/code&gt; の外で工夫して &lt;code&gt;org-mode&lt;/code&gt; 形式のリンクを生成するよりは、
&lt;code&gt;org-mode&lt;/code&gt; 自体に任せてしまうのが安心です。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/rexim/org-cliplink" target="_blank" rel="noopener"&gt;org-cliplink&lt;/a&gt; というパッケージもありますが、これだとログインが必要なページへのリンクは
(Basic 認証を設定していなければ)生成出来ません。&lt;/p&gt;
&lt;p&gt;もっと手軽に、 Chrome で見ているページへのリンクを挿入する手段として、
&lt;a href="https://github.com/ku/CreateLink" target="_blank" rel="noopener"&gt;CreateLink&lt;/a&gt; という Chrome 拡張機能を使う方法があります。&lt;/p&gt;
&lt;p&gt;以下のように改行区切りでコピーするような設定を追加します:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;%text%%newline%%url%
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;CreateLink の &lt;code&gt;%text%&lt;/code&gt; は改行をスペースに変換する仕様になっているので、区切り文字として改行を利用するのは安全なハズです。&lt;/p&gt;
&lt;p&gt;そして、以下のような独自関数を定義します:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-emacs-lisp" data-lang="emacs-lisp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;ytn-org-insert-weblink&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;interactive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;let*&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;pair&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;s-split&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;\n&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;with-temp-buffer&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;clipboard-yank&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;buffer-string&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;desc&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;first&lt;/span&gt; &lt;span class="nv"&gt;pair&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;link&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;second&lt;/span&gt; &lt;span class="nv"&gt;pair&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;org-make-link-string&lt;/span&gt; &lt;span class="nv"&gt;link&lt;/span&gt; &lt;span class="nv"&gt;desc&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;単純に改行で区切って &lt;code&gt;org-make-link-string&lt;/code&gt; に渡すだけです。&lt;/p&gt;
&lt;p&gt;これを、個人的には &lt;kbd&gt;M-L&lt;/kbd&gt; にアサインしています(&lt;a href="https://github.com/jwiegley/use-package" target="_blank" rel="noopener"&gt;use-package&lt;/a&gt; の &lt;code&gt;bind-key&lt;/code&gt; を利用しています):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-emacs-lisp" data-lang="emacs-lisp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;bind-key&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;M-L&amp;#34;&lt;/span&gt; &lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;ytn-org-insert-weblink&lt;/span&gt; &lt;span class="nv"&gt;org-mode-map&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;以上、ちょっとした小ネタでした。&lt;/p&gt;</description></item><item><title>#MadeWithAcademic</title><link>https://www.yewton.net/2020/01/06/made-with-academic/</link><pubDate>Mon, 06 Jan 2020 00:00:00 +0000</pubDate><guid>https://www.yewton.net/2020/01/06/made-with-academic/</guid><description>&lt;p&gt;&lt;a href="https://github.com/digitalcraftsman/hugo-icarus-theme" target="_blank" rel="noopener"&gt;Icarus&lt;/a&gt; がメンテされておらず Hugo 0.55.0 以降で正しく動かなくなっていたので、
自力で Icarus にパッチを充てるか、別のテーマに乗り換えるかという選択を迫られていた。&lt;/p&gt;
&lt;p&gt;せっかくなのでランディングページとブログを別にしたかったので、そういう柔軟性を備えている
&lt;a href="https://sourcethemes.com/academic/" target="_blank" rel="noopener"&gt;Academic&lt;/a&gt; というテーマを使うことにした。&lt;/p&gt;
&lt;p&gt;テーマの変更にあたって様々な知見が得られたので、そのうち記事にしたい。&lt;/p&gt;
&lt;p&gt;以下その候補:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://gohugo.io/content-management/page-bundles/" target="_blank" rel="noopener"&gt;Page Bundles&lt;/a&gt; への移行&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ox-hugo.scripter.co/doc/why-ox-hugo/" target="_blank" rel="noopener"&gt;ox-hugo&lt;/a&gt; と Academic が如何に相性がよいか
&lt;ul&gt;
&lt;li&gt;auto weight あたりが最高&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lastmod&lt;/code&gt; の自動更新や &lt;a href="https://ox-hugo.scripter.co/doc/custom-front-matter/#front-matter-extra" target="_blank" rel="noopener"&gt;Front-matter Extra&lt;/a&gt; は Academic じゃなても最高の体験&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;カスタムウィジェットの作り方&lt;/li&gt;
&lt;li&gt;ダークテーマ対応のシンタックスハイライトのやりかた&lt;/li&gt;
&lt;li&gt;conf-toml-mode を &lt;a href="https://ox-hugo.scripter.co/doc/custom-front-matter/#front-matter-extra" target="_blank" rel="noopener"&gt;Front-matter Extra&lt;/a&gt; で使う方法&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>久々の更新</title><link>https://www.yewton.net/2020/01/02/happy-new-year/</link><pubDate>Thu, 02 Jan 2020 00:00:00 +0000</pubDate><guid>https://www.yewton.net/2020/01/02/happy-new-year/</guid><description>&lt;p&gt;最近仕事用のmacを新調して環境を作り直す機会があったことと、 2020 年が始まるということもあり、久々にサイトを更新することにした。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.yewton.net/cv/"&gt;オープン職務経歴書&lt;/a&gt;を書きたかった、というのもある。&lt;/p&gt;
&lt;p&gt;更新にあたっていくつか困難があった。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;まず、このサイトのソースが最近の Hugo では動かせなくなっていた。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;このサイトのテーマには &lt;a href="https://github.com/digitalcraftsman/hugo-icarus-theme" target="_blank" rel="noopener"&gt;Icarus&lt;/a&gt; を使わせていただいているのだが、最終更新が 2017 年となっており、
Hugo 0.55.0 以降で動かなくなってしまっていたり、 Deprecated Warning が出るようになっていた。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/digitalcraftsman/hugo-icarus-theme/pull/124" target="_blank" rel="noopener"&gt;PRは出されている&lt;/a&gt; のだけれど、マージされる様子が無い。&lt;/p&gt;
&lt;p&gt;そもそも、当時のバージョンに対してカスタマイズしたレイアウトを作ってしまったので、
単純なテーマの更新だけでは追随できない。&lt;/p&gt;
&lt;p&gt;どのバージョンなら動くのか突き止めるのも骨が折れた。
&lt;a href="https://bitbucket.org/mgladdish/asdf-gohugo" target="_blank" rel="noopener"&gt;asdf-gohugo&lt;/a&gt; を入れて、少しずつバージョンを上げながら確認していった。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;asdf plugin add hugo https://bitbucket.org/mgladdish/asdf-gohugo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;そして、そもそも Hugo の使い方を忘れていた。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.yewton.net/2016/02/02/blog-with-hugo/"&gt;Hugo 導入記事&lt;/a&gt; や &lt;a href="https://www.yewton.net/2016/01/26/hugo-el/"&gt;Hugo 用 Emacs ライブラリ&lt;/a&gt; を書いておいてなんだが、当時から3年も経ってほとんど忘れてしまっていた。&lt;/p&gt;
&lt;p&gt;そこで改めて調べてみると、イマドキは org-mode で書くことも出来るらしい。&lt;/p&gt;
&lt;p&gt;この3年ですっかり org-mode 無しでは生きられない体になってしまっていたし、
せっかくなので本記事からは &lt;a href="https://ox-hugo.scripter.co/" target="_blank" rel="noopener"&gt;ox-hugo&lt;/a&gt; を使って書くことにする。&lt;/p&gt;
&lt;p&gt;使い始めるにあたって色々調べたり考えたりすることも多かったので、そのうち記事にしようと思う。
結論としては、org-mode と Hugo の組み合わせは最高だし、その橋渡しをしてくれる &lt;a href="https://ox-hugo.scripter.co/" target="_blank" rel="noopener"&gt;ox-hugo&lt;/a&gt; は本当にグッジョブだということ。&lt;/p&gt;
&lt;p&gt;&amp;hellip;&lt;/p&gt;
&lt;p&gt;そんなこんなで色々対応していたものの、デプロイする仕組みなどは当時と変わりなく動いたのでその点は助かった。&lt;/p&gt;
&lt;p&gt;org-mode で書けるようになったことだし、少しは記事を書いていきたい所だが、まずは Hugo の最新版に追従する作業が待っている…。&lt;/p&gt;</description></item><item><title>Nexus 7 2012 (grouper) に Beanstalk と ParrotMod を入れて蘇生する</title><link>https://www.yewton.net/2017/04/09/grouper-beanstalk/</link><pubDate>Sun, 09 Apr 2017 21:55:31 +0900</pubDate><guid>https://www.yewton.net/2017/04/09/grouper-beanstalk/</guid><description>&lt;p&gt;最近はじめて &lt;a href="https://amzn.to/2nXsSKh" target="_blank" rel="noopener"&gt;Fire タブレット&lt;/a&gt; をキャンペーンで購入して、
こういう本読むだけとか書い物するだけとかの単機能なタブレットも結構いいな、と思った。
そして、うちに使ってない &lt;a href="https://amzn.to/2oSEwJK" target="_blank" rel="noopener"&gt;Nexus 7&lt;/a&gt; があることを思い出した。&lt;/p&gt;
&lt;p&gt;この Nexus 7 、どうして使っていなかったかというと、
Lollipop にアップデートしてしまったから。
Nexus 7 2012 は Lollipop にアップデートしてしまうと、
動作が重過ぎて使い物にならなくなる。&lt;/p&gt;
&lt;p&gt;どうせ使いものにならないなら、ということで
&lt;a href="https://www.slimroms.net/" target="_blank" rel="noopener"&gt;SlimKat&lt;/a&gt; や
&lt;a href="https://forum.xda-developers.com/nexus-7/development/unofficial-pure-nexus-project-layers-t3243943" target="_blank" rel="noopener"&gt;PureNexus&lt;/a&gt; を
焼いて使ってみたりもしたが、
前者は軽いけど見た目や使用感がちょっと微妙( 4.4 ベースだし…)で、
後者は使っていくうちにやっぱり重くなっていって駄目だった。&lt;/p&gt;
&lt;p&gt;今回 Fire を買ってあらためて 7 インチの Android タブレットが欲しくなってしまったので、
もう一度蘇生を試みることにした。&lt;/p&gt;
&lt;p&gt;そして &lt;a href="https://www.reddit.com/r/Nexus7/comments/3h0oxg/recommended_fastlightweight_rom_for_2012_n7/" target="_blank" rel="noopener"&gt;Reddit のこのスレ&lt;/a&gt; を満つけ、
そこから &lt;a href="https://teknovenus.com/speed-up-nexus-7-f2fs-slimkat-ghost/" target="_blank" rel="noopener"&gt;Speed up the Nexus 7 with F2FS and SlimKat&lt;/a&gt; という記事に辿り着いた。&lt;/p&gt;
&lt;p&gt;元々は SlimKat と F2FS の記事だったようだが、2017 年に更新があり、
&lt;a href="https://forum.xda-developers.com/nexus-7/development/rom-beanstalk-rom-t3312870" target="_blank" rel="noopener"&gt;Beanstalk 6.0.1&lt;/a&gt; と
&lt;a href="https://forum.xda-developers.com/nexus-7/orig-development/parrotmod-speed-2012-nexus-7-emmc-fix-t3300416" target="_blank" rel="noopener"&gt;ParrotMod&lt;/a&gt; が
勧められていた(執筆者自身は試していないようだったが)。&lt;/p&gt;
&lt;h2 id="beanstalk"&gt;Beanstalk&lt;/h2&gt;
&lt;p&gt;CyanogenMod 13 (Marshmallow) をベースに作られたカスタム Rom 。
&lt;a href="https://forum.xda-developers.com/galaxy-s3/development/rom-t3370186" target="_blank" rel="noopener"&gt;フォーラム&lt;/a&gt; の記述によると、&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;Smoother than Butter&lt;br&gt;
Friendly Battery&lt;br&gt;
Tons of Features&lt;br&gt;
DirtyUnicorns Features&lt;br&gt;
Always Up-to-date&lt;br&gt;
100% Build from Source&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;…らしい。&lt;/p&gt;
&lt;h2 id="parrotmod"&gt;ParrotMod&lt;/h2&gt;
&lt;p&gt;Nexus 7 2012 をすげーいい感じにしてくれるやつ。&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;FLASH MEMORY SPEED INCREASE! up to 4x better performance WITHOUT F2FS OR DYNAMIC FSYNC&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;という速度の向上を筆頭に、様々な最適化を行って快適にしてくれるようだ。&lt;/p&gt;
&lt;h2 id="結果"&gt;結果&lt;/h2&gt;
&lt;p&gt;Amazon Kindle , YouTube 、Feedly , 1Password あたりを主に動かしているが、
アプリ起動時にたまに固まることがあるものの、大抵一度タスクキルして起動し直せば問題なく動作している。
娯楽用途としては十分な性能になった。&lt;/p&gt;
&lt;p&gt;もし、使わなくなった Nexus 7 2012 がご家庭に眠っているのなら、
Beanstalk と ParrotMod を試してみる価値はアリだと思う。&lt;/p&gt;</description></item><item><title>Atlassian から無料でTシャツをもらう方法、あるいはドラゴンの倒し方</title><link>https://www.yewton.net/2016/09/03/how-to-get-atlassian-dragon-slayer-t-shirt/</link><pubDate>Sat, 03 Sep 2016 15:34:07 +0900</pubDate><guid>https://www.yewton.net/2016/09/03/how-to-get-atlassian-dragon-slayer-t-shirt/</guid><description>&lt;p&gt;仕事で Atlassian 製品を使っていて、個人的にも便利なタスク・ドキュメント管理に欲しいな、と思い、
を読んでいた。&lt;/p&gt;
&lt;p&gt;すると気になるフレーズが目に入った。 &lt;strong&gt;「ドラゴンズレアとは何ですか？」&lt;/strong&gt; ──&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;6 つのスターター ライセンスの統合スイートをセットアップすると素晴らしい結果になりますが、セットアップ手順は複雑で時間がかかります。アトラシアンでは、アトラシアン アプリケーション スイートを統合するため方法をドラゴンズレアという説明書にまとめました。また、この困難だけれども素晴らしい旅を完了された方全員向けに、限定版アトラシアン ドラゴン スレイヤー T シャツを提供しています。今すぐ冒険を始めましょう! 勇気がある方はドラゴンに立ち向かいましょう!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;せっかくもらえるもんなら、とドラゴン退治をすることにした。&lt;/p&gt;
&lt;div class="callout flex px-4 py-3 mb-6 rounded-md border-l-4 bg-blue-100 dark:bg-blue-900 border-blue-500"
data-callout="note"
data-callout-metadata=""&gt;
&lt;span class="callout-icon pr-3 pt-1 text-blue-600 dark:text-blue-300"&gt;
&lt;svg height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&gt;&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="m16.862 4.487l1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8l.8-2.685a4.5 4.5 0 0 1 1.13-1.897zm0 0L19.5 7.125"/&gt;&lt;/svg&gt;
&lt;/span&gt;
&lt;div class="callout-content dark:text-neutral-300"&gt;
&lt;div class="callout-title font-semibold mb-1"&gt;Note&lt;/div&gt;
&lt;div class="callout-body"&gt;&lt;p&gt;&lt;strong&gt;2017/1/20 時点の注意&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;どうやら現在、 &lt;strong&gt;Tシャツを要求するためのページが 404 になってしまっている&lt;/strong&gt; ようす
(
)
。&lt;/p&gt;
&lt;p&gt;せっかくやってもTシャツはもらえないかもしれないので注意。&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="callout flex px-4 py-3 mb-6 rounded-md border-l-4 bg-blue-100 dark:bg-blue-900 border-blue-500"
data-callout="note"
data-callout-metadata=""&gt;
&lt;span class="callout-icon pr-3 pt-1 text-blue-600 dark:text-blue-300"&gt;
&lt;svg height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&gt;&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="m16.862 4.487l1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8l.8-2.685a4.5 4.5 0 0 1 1.13-1.897zm0 0L19.5 7.125"/&gt;&lt;/svg&gt;
&lt;/span&gt;
&lt;div class="callout-content dark:text-neutral-300"&gt;
&lt;div class="callout-title font-semibold mb-1"&gt;Note&lt;/div&gt;
&lt;div class="callout-body"&gt;&lt;p&gt;&lt;strong&gt;2017/2/5 時点の情報&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;どうやらサイトが復旧したようす
&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="環境要件"&gt;環境要件&lt;/h2&gt;
&lt;p&gt;ドキュメントには「最低 3 GB の RAM と 500 MB のアプリケーションファイル用の空き容量」とある。&lt;/p&gt;
&lt;p&gt;しかし、実際にやってみたところ 3 GB では全てのアプリケーションを立ち上げることが出来なかった。
最終的に 6 つのアプリケーションを稼動させることになるのだが、 5 つが限界だった。
&lt;strong&gt;最低 RAM は 4 GB は必要&lt;/strong&gt; だと思う。&lt;/p&gt;
&lt;p&gt;またディスク容量に関しては、まっさらな環境に諸々構築したあとの総使用量が 6 GB 程だった。
こちらも &lt;strong&gt;最低ストレージは 10 GB は必要&lt;/strong&gt; だと思う。&lt;/p&gt;
&lt;p&gt;自分は
を利用して構築した。
Google Compute Engine の &lt;code&gt;vCPU x 1&lt;/code&gt; (メモリ 3.75 GB)の標準インスタンスを使ったが、
前述の通りメモリが足りなくなってしまったので、 &lt;code&gt;vCPU x 2&lt;/code&gt; (メモリ 7.5 GB)のインスタンスを使う方がよいと思う。&lt;/p&gt;
&lt;p&gt;OS は &lt;strong&gt;Debian GNU/Linux 8 (jessie)&lt;/strong&gt; を使用した。&lt;/p&gt;
&lt;h2 id="here-be-dragons"&gt;Here Be Dragons&lt;/h2&gt;
&lt;p&gt;それでは
に従って冒険を始めよう。&lt;/p&gt;
&lt;p&gt;基本的には書かれてある通りにやればいいだけなのだが、いくつか自分が躓いたポイントがあるので紹介していきたい。&lt;/p&gt;
&lt;h3 id="dragons-stage-1---install-jira"&gt;
&lt;/h3&gt;
&lt;h4 id="step-1-install-java"&gt;Step 1. Install Java&lt;/h4&gt;
&lt;p&gt;まず Java を用意しなければならないのだが、なんと &lt;strong&gt;Oracle JDK 1.7.x&lt;/strong&gt; でなければならない。
のだが、
このクエストではこのバージョンしか想定していないようなので、大人しく従っておく。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget --header &lt;span class="s2"&gt;&amp;#34;Cookie: oraclelicense=accept-securebackup-cookie&amp;#34;&lt;/span&gt; http://download.oracle.com/otn-pub/java/jdk/7u79-b15/jdk-7u79-linux-x64.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Debian で Oracle Java を利用するには
にあるような作業が必要になる。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo sed -i &lt;span class="s1"&gt;&amp;#39;s/deb http:\/\/httpredir.debian.org\/debian\/ jessie main/deb http:\/\/httpredir.debian.org\/debian\/jessie main contrib/&amp;#39;&lt;/span&gt; /etc/apt/sources.list
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get update -y &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo apt-get install -y libgl1-mesa-glx libfontconfig1 libxslt1.1 libxtst6 libxxf86vm1 libgtk2.0-0 java-package
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;make-jpkg jdk-7u79-linux-x64.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dpkg -i oracle-java7-jdk_7u79_amd64.deb
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="step-2-install-your-postgresql-database-server"&gt;Step 2. Install your PostgreSQL Database Server&lt;/h4&gt;
&lt;p&gt;こちらも &lt;strong&gt;8.4.x.&lt;/strong&gt; というバージョン指定がある。
Java と同様に既に
しているため、
Debian のリポジトリでは配布されていない。
そのため、リポジトリを追加してからインストールする必要がある。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo sh -c &lt;span class="s1"&gt;&amp;#39;echo &amp;#34;deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main&amp;#34; &amp;gt; /etc/apt/sources.list.d/pgdg.list&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc &lt;span class="p"&gt;|&lt;/span&gt; sudo apt-key add -
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get update -y &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo apt-get upgrade -y &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo apt-get install -y postgresql-8.4
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="step-3-create-your-jira-database-in-postgresql"&gt;Step 3. Create your JIRA Database in PostgreSQL&lt;/h4&gt;
&lt;p&gt;Atlassian 製品はデータベースとして MySQL や PostgreSQL を利用出来る。
ただ、日本語や絵文字などマルチバイト文字を扱う場合は PostgresSQL を使うのが無難なようだ(
)。&lt;/p&gt;
&lt;p&gt;個人的にあまり馴染みがないのだけれど、このドラゴンズレアでも PostgreSQL が指定されているので従っておく。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo -u postgres createuser -S -d -r -P -E jirauser
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# パスワード入力&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo -u postgres createdb --owner jirauser --encoding utf8 jira
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="step-4-install-jira"&gt;Step 4. Install JIRA&lt;/h4&gt;
&lt;p&gt;JIRA のバージョンも指定されている。 &lt;strong&gt;6.3.15&lt;/strong&gt; を使う必要がある。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget https://www.atlassian.com/software/jira/downloads/binary/atlassian-jira-6.3.15-x64.bin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod a+x atlassian-jira-6.3.15-x64.bin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ./atlassian-jira-6.3.15-x64.bin
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;JIRA にはインストーラーがついているので簡単。&lt;/p&gt;
&lt;h3 id="step-5-set-up-jira-step-6-set-up-a-project-and-create-your-jira-dashboard"&gt;Step 5. Set Up JIRA, Step 6. Set up a Project and Create your JIRA Dashboard&lt;/h3&gt;
&lt;p&gt;あとはドキュメントに従って Web UI 上で操作を行えばよい。&lt;/p&gt;
&lt;p&gt;もしかすると、以下のようなよく分からないエラーに遭遇するかもしれない。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;let.ServletException: javax.servlet.jsp.JspTagException: Soy rendering failed for template &amp;#39;%s&amp;#39;.
説明 The server encountered an internal error that prevented it from fulfilling this request.
例外
org.apache.jasper.JasperException: javax.servlet.ServletException: javax.servlet.jsp.JspTagException: Soy rendering failed for template &amp;#39;%s&amp;#39;.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;環境依存なのか、言語を日本語にしていた影響なのか分からないが、エラーが発生したらブラウザをリロードすれば大体直っていた。&lt;/p&gt;
&lt;h3 id="dragons-stage-2---jira-add-ons"&gt;
&lt;/h3&gt;
&lt;p&gt;ドキュメントに従うだけで特に問題はないが、 Capture for JIRA を動かそうとしたときに以下のエラーが出ていた。&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;Your Bonfire license has expired. Please visit My Atlassian to renew&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;ボンファイアとはなんのこったい、と思ったのだが、どうやら Capture for JIRA のことらしい。
インストール後のアクティベーションが正常に終わっていなかったようだった。
改めて管理画面から評価用ラインセンスを払い出してことなきを得た。&lt;/p&gt;
&lt;h3 id="dragons-stage-3---install-confluence"&gt;
&lt;/h3&gt;
&lt;h4 id="step-1-create-your-confluence-database-in-postgresql"&gt;Step 1. Create your Confluence Database in PostgreSQL&lt;/h4&gt;
&lt;p&gt;JIRA のときと同様に行う。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo -u postgres createuser -S -d -r -P -E confuser
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo -u postgres createdb --owner confuser --encoding utf8 confluence
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="step-2-install-confluence"&gt;Step 2. Install Confluence&lt;/h4&gt;
&lt;p&gt;インストールまでは以下の通り:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget https://www.atlassian.com/software/confluence/downloads/binary/atlassian-confluence-5.7.1-x64.bin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod a+x atlassian-confluence-5.7.1-x64.bin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ./atlassian-confluence-5.7.1-x64.bin
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;この後、&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;Because Confluence will be running on the same machine as JIRA (already installed), you need to ensure that the URL paths are different for Confluence and JIRA.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;という理由で設定ファイルを一部いじる必要がある。
以下のように一旦 Confluence を停止、設定を修正して再起動する:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo /opt/atlassian/confluence/bin/stop-confluence.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo sed -i &lt;span class="s1"&gt;&amp;#39;s/&amp;lt;Context path=&amp;#34;&amp;#34;/&amp;lt;Context path=&amp;#34;\/confluence&amp;#34;/&amp;#39;&lt;/span&gt; /opt/atlassian/confluence/conf/server.xml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo /opt/atlassian/confluence/bin/start-confluence.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="step-3-以降"&gt;Step 3 以降&lt;/h4&gt;
&lt;p&gt;ドキュメントに従って進めれば問題ないはず。&lt;/p&gt;
&lt;h3 id="dragons-stage-4---install-team-calendars-in-confluence"&gt;
&lt;/h3&gt;
&lt;p&gt;ドキュメントに従って Web UI を操作すれば &amp;#x1f44c; 。&lt;/p&gt;
&lt;h3 id="dragons-stage-5---install-fisheye-and-crucible"&gt;
&lt;/h3&gt;
&lt;h4 id="step-1-install-mercurial"&gt;Step 1. Install Mercurial&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get -y install mercurial
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="step-2-create-your-fisheye-database-in-postgresql"&gt;Step 2. Create your FishEye Database in PostgreSQL&lt;/h4&gt;
&lt;p&gt;これまでと同様に行う:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo -u postgres createuser -S -d -r -P -E fishuser
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo -u postgres createdb --owner fishuser --encoding utf8 fisheye
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="step-3-install-fisheye-and-crucible"&gt;Step 3. Install FishEye and Crucible&lt;/h4&gt;
&lt;p&gt;インストーラーが無いので若干手順が複雑になる。&lt;/p&gt;
&lt;p&gt;まず必要なファイルをダウンロードして展開する:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget https://www.atlassian.com/software/fisheye/downloads/binary/fisheye-3.7.0.zip
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo unzip -d /opt/atlassian/ fisheye-3.7.0.zip
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;アプリケーションのデータディレクトリを作成する。
他のアプリケーションに合わせて &lt;code&gt;/var/atlassian/application-data/fecru&lt;/code&gt; にする:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo mkdir /var/atlassian/application-data/fecru
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;FISHEYE_INST&lt;/code&gt; という環境変数が上記のデータディレクトリを指すようにする:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo sh -c &lt;span class="s1"&gt;&amp;#39;echo &amp;#34;export FISHEYE_INST=/var/atlassian/application-data/fecru&amp;#34; &amp;gt; /etc/profile.d/fecru.sh&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;source&lt;/span&gt; /etc/profile.d/fecru.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;設定ファイルを一部修正しつつ配置する:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo cp /opt/atlassian/fecru-3.7.0/config.xml /var/atlassian/application-data/fecru/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo sed -i &lt;span class="s1"&gt;&amp;#39;s/&amp;lt;web-server&amp;gt;/&amp;lt;web-server context=&amp;#34;\/fisheye&amp;#34;&amp;gt;/&amp;#39;&lt;/span&gt; /var/atlassian/application-data/fecru/config.xml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Fecru サービスを稼動させるためのユーザーを作成する:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo useradd -m -c &lt;span class="s1"&gt;&amp;#39;Atlassian FishEye/Crucible&amp;#39;&lt;/span&gt; fecru
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;権限を適切に修正し、サービスを立ち上げる:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chown fecru -R /opt/atlassian/fecru-3.7.0/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chown fecru -R /var/atlassian/application-data/fecru/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nohup sudo -u fecru /opt/atlassian/fecru-3.7.0/bin/run.sh &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;本来は systemd とかでちゃんとサービス化した方がいいと思う &amp;#x1f61f;&lt;/p&gt;
&lt;h4 id="step-4-以降"&gt;Step 4 以降&lt;/h4&gt;
&lt;p&gt;ドキュメントに従えば &amp;#x1f44c;&lt;/p&gt;
&lt;h3 id="dragons-stage-6---get-jira-and-fisheye-talking"&gt;
&lt;/h3&gt;
&lt;p&gt;
にあるように、恐らく FishEye の Site URL を設定してからでないと JIRA リンクが上手く動かないので、
まず FishEye 上で Administration -&amp;gt; Global Settings -&amp;gt; Server から Site URL を設定しておく。&lt;/p&gt;
&lt;p&gt;あとはドキュメントの手順通り設定を行えばよい。&lt;/p&gt;
&lt;h3 id="dragons-stage-7---get-jira-and-crucible-talking"&gt;
&lt;/h3&gt;
&lt;p&gt;ドキュメントの通りで &amp;#x1f197;&lt;/p&gt;
&lt;h3 id="dragons-stage-8---install-bamboo"&gt;
&lt;/h3&gt;
&lt;h4 id="step-1-create-your-bamboo-database-in-postgresql"&gt;Step 1. Create your Bamboo Database in PostgreSQL&lt;/h4&gt;
&lt;p&gt;これまでと同様:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo -u postgres createuser -S -d -r -P -E bamuser
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo -u postgres createdb --owner bamuser --encoding utf8 bamboo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="step-2-install-bamboo"&gt;Step 2. Install Bamboo&lt;/h4&gt;
&lt;p&gt;Fecru と同様にこちらもインストーラーが無いので複雑な手順が必要になる:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo -u postgres createuser -S -d -r -P -E bamuser
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo -u postgres createdb --owner bamuser --encoding utf8 bamboo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget https://www.atlassian.com/software/bamboo/downloads/binary/atlassian-bamboo-5.3.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo useradd -m -c &lt;span class="s1"&gt;&amp;#39;Atlassian Bamboo&amp;#39;&lt;/span&gt; bamboo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo tar -C /opt/atlassian -zxvf atlassian-bamboo-5.3.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chown bamboo -R /opt/atlassian/atlassian-bamboo-5.3
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo sh -c &lt;span class="s1"&gt;&amp;#39;echo &amp;#34;bamboo.home=/home/bamboo&amp;#34; &amp;gt; /opt/atlassian/atlassian-bamboo-5.3/atlassian-bamboo/WEB-INF/classes/bamboo-init.properties&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo sed -i &lt;span class="s1"&gt;&amp;#39;s/&amp;lt;Context path=&amp;#34;&amp;#34;/&amp;lt;Context path=&amp;#34;\/bamboo&amp;#34;/&amp;#39;&lt;/span&gt; /opt/atlassian/atlassian-bamboo-5.3/conf/server.xml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo -u bamboo /opt/atlassian/atlassian-bamboo-5.3/bin/start-bamboo.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="step-3-set-up-bamboo"&gt;Step 3. Set Up Bamboo&lt;/h4&gt;
&lt;p&gt;まず Maven 3 の環境を整える必要がある。
ドキュメントの指示通
り
をインストールする:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo sh -c &lt;span class="s1"&gt;&amp;#39;echo &amp;#34;deb https://sdkrepo.atlassian.com/debian/ stable contrib&amp;#34; &amp;gt; /etc/apt/sources.list.d/atlassian.list&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys B07804338C015B73
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get install -y apt-transport-https
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get -y update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get install -y atlassian-plugin-sdk
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;あとはドキュメント通りに進めればよいが、
Maven Executable のパスを指定する箇所は
&lt;code&gt;/usr/share/atlassian-plugin-sdk-6.2.9/apache-maven-3.2.1&lt;/code&gt; のように
指定しなければならない(ドキュメントには &lt;code&gt;/usr/local/Atlassian/atlassian-plugin-sdk/apache-maven&lt;/code&gt; とあるがそこには無い)。&lt;/p&gt;
&lt;h3 id="dragons-stage-9---bamboo-gadgets-and-jira-victory"&gt;
&lt;/h3&gt;
&lt;p&gt;ドキュメントの指示通り JIRA に Bamboo ガジェットを追加すれば完了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Battle is Won, the Dragon is Slain!&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="tシャツを要求する"&gt;Tシャツを要求する&lt;/h2&gt;
&lt;p&gt;ページの指示通りやると、クーポンコードがもらえるので、
それを使って注文すればいい。&lt;/p&gt;
&lt;p&gt;自分の注文情報はこんな感じ:&lt;/p&gt;
&lt;iframe src="https://drive.google.com/file/d/0B4XWl5W7tB7IcFRKdlhFTnpZV2s/preview" width="640" height="480"&gt;&lt;/iframe&gt;
&lt;p&gt;注文してから 1〜2 週間で届くらしい。&lt;/p&gt;</description></item><item><title>三ヶ月以上ぶりに何かを書く</title><link>https://www.yewton.net/2016/08/29/misc/</link><pubDate>Mon, 29 Aug 2016 22:29:35 +0900</pubDate><guid>https://www.yewton.net/2016/08/29/misc/</guid><description>&lt;p&gt;前回の更新から三ヶ月以上経ってしまった。
月日が経つのは早いものだ。&lt;/p&gt;
&lt;p&gt;まとめたいことがいくつかあるので、まとめておく。&lt;/p&gt;
&lt;h2 id="atlassian-からtシャツをタダでもらう方法"&gt;Atlassian からTシャツをタダでもらう方法&lt;/h2&gt;
&lt;p&gt;Atlassian の製品のセットアップを公式ドキュメントに従って行うとTシャツが貰える。&lt;/p&gt;
&lt;p&gt;実際もらえたのでやり方をまとめたい。&lt;/p&gt;
&lt;h2 id="無料のプライベート-wiki-は-google-sites-が最強な気がする"&gt;無料のプライベート Wiki は Google Sites が最強な気がする&lt;/h2&gt;
&lt;p&gt;Atlassian の構築はそもそも個人的に家庭で Confluence 的なのを使いたかったので手を出したものだった。&lt;/p&gt;
&lt;p&gt;とはいえ金がかかるのでいい方法は無いかと探していたら、 Google Sites に辿りついた。&lt;/p&gt;
&lt;h2 id="org-publish-で気軽に-web-サイトを作る"&gt;&lt;code&gt;org-publish&lt;/code&gt; で気軽に Web サイトを作る&lt;/h2&gt;
&lt;p&gt;無料のプライベート Wiki を探している過程で org-publish にも手を出した。&lt;/p&gt;
&lt;p&gt;プライベートにするのが面倒だったので諦めたけれど、
org-mode で書いた内容を、見た目もほぼそのまま公開出来るというのは便利かもしれないのでまとめたい。&lt;/p&gt;
&lt;h2 id="helm-から-ivy-に移行したい"&gt;helm から ivy に移行したい&lt;/h2&gt;
&lt;p&gt;helm が活発過ぎて周辺エコシステムが付いていけないとか、
ivy の方が軽量でよいとかいう話を聞くので、 ivy に移行してみたい。&lt;/p&gt;
&lt;p&gt;ヘビーに helm 使ってるわけでないので、さくっと乗り換えたい気持ち。&lt;/p&gt;
&lt;h2 id="ifttt-do-button-で定型文を-slack-に投稿する"&gt;IFTTT Do Button で定型文を Slack に投稿する&lt;/h2&gt;
&lt;p&gt;普通に使ってると、IFTTT はひとつの Slack Team としか連携出来ないので、
MAKE をアクションにして Web Hook でどうにかした話をまとめたい。&lt;/p&gt;</description></item><item><title>Spacemacs から helm と persp-mode の設定をパクろうと思ったけど難しかった</title><link>https://www.yewton.net/2016/05/04/helm-persp/</link><pubDate>Wed, 04 May 2016 19:45:26 +0900</pubDate><guid>https://www.yewton.net/2016/05/04/helm-persp/</guid><description>&lt;p&gt;&lt;a href="https://github.com/syl20bnr/spacemacs/blob/master/layers/%2Bwindow-management/spacemacs-layouts/funcs.el" target="_blank" rel="noopener"&gt;この辺&lt;/a&gt; を参考にせよ、
と persp-mode 公式に書いてあったので、パクれそうかやってみた。&lt;/p&gt;
&lt;p&gt;結論としては、出来なかった。
なので、 併せて記載されていた &lt;a href="https://gist.github.com/Bad-ptr/304ada85c9ba15013303" target="_blank" rel="noopener"&gt;こっち&lt;/a&gt; の設定を使う状態のまま。&lt;/p&gt;
&lt;p&gt;Spacemacs の設定は、 Spacemacs 独自のステートの概念(Vimmer が喜ぶやつ)と密接に関連しているようで、
素の Emacs に組込むのは骨が折れそうだった。&lt;/p&gt;
&lt;p&gt;そもそも何で Spacemacs の設定をパクろうとしていたかというと、
後者の設定だと、 &lt;code&gt;C-x b&lt;/code&gt; したときに前のバッファが選択されずに
現在のバッファが選択された状態になるのが違和感があったから、だった。
素の Emacs では単に &lt;code&gt;C-x b RET&lt;/code&gt; としたときは、前のバッファに戻るという挙動になる。
もしかしたら Spacemacs では元の挙動を再現した実装になっているのかもしれない、
と思って見てみたが、前述の通り失敗に終わった。&lt;/p&gt;
&lt;p&gt;persp-mode では、直前のバッファが現在のパースペクティブに含まれているとは限らないから、仕方ないのかな…。&lt;/p&gt;</description></item><item><title>『いけにえと雪のセツナ』感想</title><link>https://www.yewton.net/2016/05/04/setsuna/</link><pubDate>Wed, 04 May 2016 16:10:11 +0900</pubDate><guid>https://www.yewton.net/2016/05/04/setsuna/</guid><description>&lt;p&gt;この間 Amazon で『いけにえと雪のセツナ』が 2,000 円だったので買ってみた。&lt;/p&gt;
&lt;p&gt;曰く、「あの頃、みんなRPGに夢中だった。
当時遊んだ数多のRPGは、今もぼくたちの記憶に強く残っている。
パーティ編成、街での買い物、ダンジョン攻略、ギリギリで倒した強敵たち。
そして、エンディングで流した涙－。名作たちが与えてくれた感動は、今もなお色褪せない。とりもどそう、ぼくたちのRPG。」&lt;/p&gt;
&lt;p&gt;…凄い売り文句だ。&lt;/p&gt;
&lt;p&gt;バトルシステムはあのクロノ・トリガーをベースにしているらしい。
否が応にも期待値が高まる謳い文句だ。
高まりすぎて不安になる。&lt;/p&gt;
&lt;p&gt;ネットのレビューを見てみると、やっぱりその期待値とのギャップに落胆している人が多いように見受けられた。
個人的には、単体のゲームとしてみればすごく楽しかったし、確かに荒削りな部分もあったけれど、
今後に大いに期待したくなる内容だったと思う。&lt;/p&gt;
&lt;p&gt;Tokyo RPG Factory は、こういう意欲的な作品を今後も是非リリースしていって欲しい。
いちユーザーとしてそう強く願う。&lt;/p&gt;
&lt;p&gt;個人的にプレイしていて色々と思うところがあったので、まとめておきたくなったのでまとめる。
ネタバレ全開。&lt;/p&gt;
&lt;h2 id="開発者の制限プレイ"&gt;(開発者の)制限プレイ&lt;/h2&gt;
&lt;p&gt;なんといっても本作、雪国しか出てこない。&lt;/p&gt;
&lt;p&gt;本当にずーっと雪景色で、たまに古代遺跡の石畳を見るくらい。
プレイ時間の大部分は白い画面と向きあうことになる。&lt;/p&gt;
&lt;p&gt;さらに、音楽はピアノオンリーである。
さすがにバトルシーンでは多少パーカッションやベースが入ったりもするが、ピアノが常にメインとなる。
ピアノフォルテの面目躍如といったところ。&lt;/p&gt;
&lt;p&gt;こういう制限のなかで、いかに面白く見せられるか、というところに挑戦する姿勢が、
ファミコン時代の同時発色数4色、音は3音+ノイズだけだったころと通じるものを感じた。
やっぱり、日本人は限られたリソースの中で工夫してよいものを作るっていうのが、
得意とするところなんじゃないかなぁ、などと日本人観に思いを馳せてみたりもした。
舞台が雪国っていう中で、火属性無双にならないようにとか、
魔物のデザインとか、すごく苦労したんじゃないかと思う。&lt;/p&gt;
&lt;p&gt;この制限が、結果としてよい方向にいったわけでは必ずしもないと思うけれども、
自分はこの挑戦する姿勢がすごく好きだった。&lt;/p&gt;
&lt;p&gt;次は南国+ウクレレ縛りプレイとかに挑戦してもらいたい。&lt;/p&gt;
&lt;h2 id="装備法石システム"&gt;装備+法石システム&lt;/h2&gt;
&lt;p&gt;本作の装備品は、武器と法器の2種類しかない。
この点が残念だという人もいるらしい。
個人的には、兜盾鎧小手みたいに分かれている意味って、
雰囲気作り以上の意味はないように思えるので、特に気にならなかった。
単純な攻撃力や防御力だけではなく、
サポート効果も加味して装備を整えるという本質的な部分は、
法石システムによって実現されている。&lt;/p&gt;
&lt;p&gt;今後のことを考えて昇華率アップ系の法器にするか、
それともいま、このバトルを乗り切るための法器にするか、
みたいなことに頭を悩ますのも楽しかった。&lt;/p&gt;
&lt;p&gt;ただ、魔法は法石じゃないほうが、嬉しかったかな…。
連携技もすごい豊富でワクワクするのに、
セットする法石に制限があるので、
「とりあえず見るだけ見てみたい」みたいなのをやりたくても出来ない。
クロノ・トリガーだったら、キャラの組み合わせを変えるだけでよかったので、
本作では法石の組み合わせも変えないといけないのが、単に手間にしか思えなかった…。&lt;/p&gt;
&lt;h2 id="バトル全般"&gt;バトル全般&lt;/h2&gt;
&lt;p&gt;〈グラーティア〉 + 〈久遠の剣閃〉とか、
そういうものすごく相性のよい魔法の組合せに気付いてしまってからは、一気にバトルが大味になってくる。&lt;/p&gt;
&lt;p&gt;でもまあ、こういうのが運用出来るようになるのがそもそも終盤だし、
俺つえー出来るための組合せを探すのもそれはそれで楽しいので、あんまり気になっていない。
自分がヌルゲーマーだからかもしれない…。
〈ガグンラーズ〉があればMP補給無用で雑魚はサクサク片づくのとか、非常に助かったし。
〈叫ぶ〉+〈パーマネンス〉+ 〈ユグドラシル〉 + 〈アルティメット〉 でエンド無双になるのとか快感だったし。
クロノ・トリガーも終盤シャイニングだけ唱えてればだいたいなんとかなったし、そんなもん。
中盤は中盤で、エンドの〈回転斬り〉無双だった気もするが…。
まあそれはそれで「お、大体回転斬りでいけるやん!」って気づく過程が楽しかった。&lt;/p&gt;
&lt;p&gt;全体的に、MP温存せずに雑魚にもガンガン使っていく感じで進められるのが快適だった。&lt;/p&gt;
&lt;p&gt;キャラ毎の個性もハッキリしていてよかったけれど、
結局エンド+クオン+(セツナ or キール)最強だなーということで、
あんまり他のメンバーを使わなくなってしまった。
ディノタウルス系用にブロウビート要因のヨミを使うことはあったけど、それくらい。
まあ、クロノ・トリガーでも魔王やカエルは趣味枠だった気がする…。&lt;/p&gt;
&lt;h2 id="法石に蝕まれた魔物"&gt;法石に蝕まれた魔物&lt;/h2&gt;
&lt;p&gt;隠し中ボスみたいなのが攻略ルート上に普通に出現する。
気付かずにバトルを仕掛けると普通に全滅して普通にゲームオーバーになる。&lt;/p&gt;
&lt;p&gt;この理不尽さも、懐しいかも…。&lt;/p&gt;
&lt;p&gt;まあ本作では100％逃走可能なアイテムがあるので、実際はそこまで脅威ではない。
とはいえ、こういうのに出くわすまではそもそも逃げることなんてなかったので、
逃走用アイテムがあることも忘れていたりするのだけれど。&lt;/p&gt;
&lt;p&gt;こういう微妙にプレイヤーを突き放した感じも、なんだか懐しい。&lt;/p&gt;
&lt;h2 id="ストーリー"&gt;ストーリー&lt;/h2&gt;
&lt;p&gt;エンドやセツナに感情移入出来ないとか、選択肢の意味がほとんど無いとか、
そういう評判をネット上ではよく見かけた。&lt;/p&gt;
&lt;p&gt;個人的には、そこはそんなに気にならなかった。
選択肢しだいで、クオンがちょっとエンドのこと見直してくれたり、
エンドが謎にチームリーダーとして慕われてたりとか、
素直に嬉しかったし、にこにこしながら見ることが出来た。&lt;/p&gt;
&lt;p&gt;セーブポイントが伏線になってたりとか、そういうところも好き。
昔からたまにある設定だから目新しさはないけど。&lt;/p&gt;
&lt;p&gt;どんどんみんなの絆が深まっていくのに、旅の目的はセツナが無事に死ぬこと、
っていう矛盾に悶々と出来たのはよかった。&lt;/p&gt;
&lt;p&gt;ただ、エンドやキトが何者なのか？とか、
絶海群島の何のイベントも起きない人々は何なのか？とか、
もう少し知りたかった。もやもやする。
想像の余地を残されたのだろうか。うーん、困る。&lt;/p&gt;
&lt;h2 id="vita-版"&gt;Vita 版&lt;/h2&gt;
&lt;p&gt;せっかくゲームはいい出来なのに、処理落ちがホントにひどい。
一番最初に使える連携技の時点で処理落ちする。
パーティメンバーを全員表示するたびに処理落ちする。
最終的に慣れてしまったけれど…。&lt;/p&gt;
&lt;p&gt;最悪なのは、エンディングイベント中にアプリケーションエラーで落ちたこと。
一番落ちてはならぬところだぞ…。&lt;/p&gt;
&lt;p&gt;これは Tokyo RPG Factory を恨めばいいのか、
Unity を恨めばいいのか、 Sony を恨めばいいのか、どれなんだ。
教えてくれ。&lt;/p&gt;
&lt;p&gt;ロード時間も長めだけれど、 PS 時代もこんなもんだったなーくらいの感覚でそこまで気にはならなかった。&lt;/p&gt;
&lt;h2 id="総評"&gt;総評&lt;/h2&gt;
&lt;p&gt;ゲームとしては値段分の価値が十分あるし、これからもこういう作品をどんどん出してほしいと思える内容だった。&lt;/p&gt;
&lt;p&gt;ただ、 Vita 版はゲーム性以外の部分がかなり残念…。&lt;/p&gt;
&lt;p&gt;もし次回作を出すならフルプライスで買うから、変なハード間差異だけは出さないでほしい…。&lt;/p&gt;</description></item><item><title>三ヶ月ぶりに更新再開した日</title><link>https://www.yewton.net/2016/05/03/diary/</link><pubDate>Tue, 03 May 2016 23:27:26 +0900</pubDate><guid>https://www.yewton.net/2016/05/03/diary/</guid><description>&lt;p&gt;前回の更新から平気で3ヶ月経っていた。
光陰矢のごとしである。&lt;/p&gt;
&lt;p&gt;一個多少マトモな記事を上げたら何か燃え尽きてしまったのと、
仕事が妙に重圧になっていて気持ちがアガらなかったのと、
色々あって全然更新しなかった。&lt;/p&gt;
&lt;p&gt;スクラム入門の翻訳も全然やってない。&lt;/p&gt;
&lt;p&gt;いやはや。&lt;/p&gt;
&lt;p&gt;やったことといえば、 &lt;code&gt;.emacs.d&lt;/code&gt; の大幅リニューアルくらい。
結果物は &lt;a href="https://github.com/yewton/.emacs.d" target="_blank" rel="noopener"&gt;こちら&lt;/a&gt;。
&lt;code&gt;.emacs.d&lt;/code&gt; 弄りは無限に時間取られるな…。&lt;/p&gt;
&lt;p&gt;まあ、その甲斐あって、以前よりさらに快適な作業環境が整った、ハズ。
かっこいいモードラインとか、いいよね。
僕はニワカイーマクサーなので、そういうところを頑張ってしまう。&lt;/p&gt;
&lt;p&gt;あと、記事の元になる Hugo ファイルを BitBucket のプライベートリポジトリに移した。
これで気兼ねなく、プライベートな内容も記録出来るようになった。&lt;/p&gt;
&lt;p&gt;この連休中に、 persp-mode の設定を spacemacs を参考に変更するのと、
Scala 製 Slack ボットのデプロイ方法を考えるのと、
いくつか追加でボットを作成するのをやっておきたい。&lt;/p&gt;</description></item><item><title>WordPressをHTTP/2+HHVMで動かす環境をdocker-composeで構築してみた</title><link>https://www.yewton.net/2016/02/21/wordpress-http2-hhvm/</link><pubDate>Sun, 21 Feb 2016 22:49:52 +0900</pubDate><guid>https://www.yewton.net/2016/02/21/wordpress-http2-hhvm/</guid><description>&lt;h2 id="tldr"&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/yewton/wordpress-nginx-http2-hhvm" target="_blank" rel="noopener"&gt;このリポジトリ&lt;/a&gt;を &lt;code&gt;clone&lt;/code&gt; して &lt;code&gt;docker-compose up -d&lt;/code&gt; して下さい
(要 &lt;a href="https://github.com/docker/compose/releases/tag/1.6.0" target="_blank" rel="noopener"&gt;バージョン 1.6.0 以上&lt;/a&gt;)。
その後 &lt;code&gt;open &amp;quot;https://$(docker-machine ip default)&amp;quot;&lt;/code&gt; すると、ブラウザでWordPressが立ち上がります。&lt;/p&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://www.yewton.net/media/2016-02-21_224951/wordpress.png" alt="デモ" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id="動機"&gt;動機&lt;/h2&gt;
&lt;p&gt;WordPressをHHVMで動かしたら超速くなった!やったぜ!!という記事はをよく見るのだけれど、
具体的にどうやって構築しているのか解説している記事があんまり無かったので、実際にやってみることにしました。&lt;/p&gt;
&lt;p&gt;ついでに、HTTP/2で提供出来るとイケてる気がしたので、併せて対応してみることにします。&lt;/p&gt;
&lt;h2 id="hhvm"&gt;HHVM&lt;/h2&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://www.yewton.net/media/2016-02-21_224951/hugo.png" alt="HHVM" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;a href="https://hhvm.com/" target="_blank" rel="noopener"&gt;HHVM&lt;/a&gt;は、Facebookがオープンソースとして開発している仮想実行環境で、
&lt;a href="https://php.net/" target="_blank" rel="noopener"&gt;PHP&lt;/a&gt;と&lt;a href="https://hacklang.org/" target="_blank" rel="noopener"&gt;Hack&lt;/a&gt;を動かすための環境らしいです。&lt;/p&gt;
&lt;p&gt;まぁ、個人的にはHackもHHVMも &lt;strong&gt;すごいPHP&lt;/strong&gt; ぐらいの認識しかありませんが…。
Hackは言語的にすごくて、HHVMは実行環境がすごい。今回用があるのはHHVMだけです。&lt;/p&gt;
&lt;h2 id="http2"&gt;HTTP/2&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://http2.github.io/" target="_blank" rel="noopener"&gt;HTTP/2&lt;/a&gt;は… &lt;strong&gt;すごいHTTP&lt;/strong&gt; です。&lt;/p&gt;
&lt;p&gt;HTTP/1.xとの互換性を保ちつつ、効率化したもののようです。ヘッダの圧縮とか、リクエストの多重化とか。
&lt;a href="https://summerwind.jp/docs/rfc7540/" target="_blank" rel="noopener"&gt;RFC7540 日本語訳&lt;/a&gt;や&lt;a href="https://http2.info/faq.html#who-made-http2" target="_blank" rel="noopener"&gt;日本語のFAQ&lt;/a&gt;もあります。
自分は全然見てないけれど…必要になったら読みます。&lt;/p&gt;
&lt;p&gt;とにかく、このプロトコルで配信するだけでより効率的でより早くなる、ということです。&lt;/p&gt;
&lt;h3 id="http2-の実装"&gt;HTTP/2 の実装&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://nginx.org/en/" target="_blank" rel="noopener"&gt;nginx&lt;/a&gt;の1.9.5からHTTP/2をサポートしているようです&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;。
&lt;a href="https://hub.docker.com/_/nginx/" target="_blank" rel="noopener"&gt;公式Dockerリポジトリ&lt;/a&gt;で配信されている最新イメージでもちゃんとサポートされていました。&lt;/p&gt;
&lt;p&gt;他にも&lt;a href="https://httpd.apache.org/" target="_blank" rel="noopener"&gt;Apache HTTP Server 2.4.17+&lt;/a&gt;や
&lt;a href="https://dena.com/intl/" target="_blank" rel="noopener"&gt;DeNA&lt;/a&gt;の&lt;a href="https://h2o.examp1e.net/" target="_blank" rel="noopener"&gt;H2O&lt;/a&gt;など&lt;a href="https://github.com/http2/http2-spec/wiki/Implementations" target="_blank" rel="noopener"&gt;色々ある&lt;/a&gt;ようです。&lt;/p&gt;
&lt;p&gt;今回はApacheよりは速かろうというのと、WordPress稼動の実例も多いことから、nginxを選択しました。適当。&lt;/p&gt;
&lt;h2 id="構成"&gt;構成&lt;/h2&gt;
&lt;p&gt;リライトルールとか複雑なリクエスト制御が不要なら、
HHVMに組込みのWebサーバーがあるのでそれを使うのが簡単だし、速度面でも問題なさそうです。&lt;/p&gt;
&lt;p&gt;ただ、WordPressでパーマリンクを利用する場合はURLのリライトが必須です。&lt;/p&gt;
&lt;p&gt;HHVMでもバーチャルホスト切ってリライトの設定するとか出来るみたいですが、
iniファイルに設定書いていくのは何だかしんどそうです。&lt;/p&gt;
&lt;p&gt;他にもSSLとか静的ファイルの配信とか諸々考えると、餅は餅屋ということでリバースプロキシを立てた方がよさそうですね。&lt;/p&gt;
&lt;p&gt;というわけで、リバースプロキシとして nginx を立てて、HHVMをFastCGIモードで起動してバックエンドとします。&lt;/p&gt;
&lt;p&gt;今回はとにかくお手軽に手元で動かしてみたかったので、諸々Dockerで動かすことにしました。
雑に図解すると以下のような感じです:&lt;/p&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://www.yewton.net/media/2016-02-21_224951/structure.png" alt="構成図" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;FrontとかBackはDockerの&lt;a href="https://docs.docker.com/engine/userguide/networking/dockernetworks/#user-defined-networks" target="_blank" rel="noopener"&gt;ユーザー定義ネットワーク&lt;/a&gt;です。
&lt;a href="https://github.com/docker/docker/blob/master/CHANGELOG.md#1100-2016-02-04" target="_blank" rel="noopener"&gt;Docker 1.10.0&lt;/a&gt;で link に代わるものとして導入されたような気がします。
&lt;code&gt;/etc/hosts&lt;/code&gt; じゃなくてDNSで名前解決出来るようになってて最高にハッピーですね。&lt;/p&gt;
&lt;p&gt;FastCGIはUnixソケットで通信した方が速いと思うんですが、
今回は nginx と HHVM を別々のコンテナで動かすので、TCPで通信するようにしました。
同一システム上にFastCGIサーバとプロセスが稼動するって、実環境でもあんまり無いような気がするけど、どうなんだろう？&lt;/p&gt;
&lt;p&gt;コンテナひとつひとつ立てていくのは辛いので、常套手段の &lt;code&gt;docker-compose&lt;/code&gt; を使って作ります。&lt;/p&gt;
&lt;h2 id="動かす"&gt;動かす&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/yewton/wordpress-nginx-http2-hhvm" target="_blank" rel="noopener"&gt;このリポジトリ&lt;/a&gt;に実際に稼動するものが置いてあります。
&lt;code&gt;clone&lt;/code&gt; して &lt;code&gt;docker-compose up -d&lt;/code&gt; すれば、HTTP/2でWordPressが動いている様子が確認出来ます。&lt;/p&gt;
&lt;p&gt;nginxやHHVMの設定はほぼデフォルトのままいじってないので、本気で動かすなら細かいチューニングは必要です。
が、全体の構成は実環境でもこのようになると思います。&lt;/p&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://www.yewton.net/media/2016-02-21_224951/wordpress.png" alt="デモ" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id="終わりに"&gt;終わりに&lt;/h2&gt;
&lt;p&gt;以上で、お手軽に手元でHTTP/2+HHVMなWordPressを試すことが出来るようになりました。&lt;/p&gt;
&lt;p&gt;あとは実環境へのデプロイだけなんですが、さてどうしたものか。
&lt;code&gt;docker-compose.yml&lt;/code&gt; からいい感じにデプロイしてくれるような何か、ありませんかねぇ。&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;&lt;a href="https://www.nginx.com/blog/nginx-1-9-5/" target="_blank" rel="noopener"&gt;HTTP/2 Supported with NGINX Open Source 1.9.5 | NGINX&lt;/a&gt;&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description></item><item><title>VM関連ファイルを外部ストレージに保存して空き容量を確保する</title><link>https://www.yewton.net/2016/02/19/save-storage-space-by-moving-vm-related-files-to-ex-storage/</link><pubDate>Fri, 19 Feb 2016 00:00:00 +0900</pubDate><guid>https://www.yewton.net/2016/02/19/save-storage-space-by-moving-vm-related-files-to-ex-storage/</guid><description>&lt;h2 id="何かと容量を食うvm関連ファイル"&gt;何かと容量を食うVM関連ファイル&lt;/h2&gt;
&lt;p&gt;DockerやらVagrantやらで作業していると、いつのまにかディスク容量が逼迫していることがありますよね。&lt;/p&gt;
&lt;p&gt;自分も128GB SSDのMacBook Proを使っているので、結構いっぱいいっぱいでした。&lt;/p&gt;
&lt;p&gt;そこで拡張ストレージを用意して、容量を食いがちなVM関連のファイルを移動することにしました。&lt;/p&gt;
&lt;h3 id="参考mac用の拡張ストレージ"&gt;(参考)Mac用の拡張ストレージ&lt;/h3&gt;
&lt;p&gt;USBで外付けするようなのだと持ち運びに不便なので、
のような本体のSDカードスロットに差せるようなタイプを個人的には使っています。
iSliceの場合はただのアダプタなので別途128GBのmicroSDカードを調達する必要がありますが、ストレージと一体になっているモノよりは若干割安です。&lt;/p&gt;
&lt;h2 id="vagrant"&gt;Vagrant&lt;/h2&gt;
&lt;p&gt;Vagrant用のBoxファイルとVMイメージの保存場所を変える際には、以下の記事が参考になります:&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;上記の記事を参考に諸々のファイルの移動、VB上の設定を済ませたら、
以下のようなコマンドを &lt;code&gt;.bashrc&lt;/code&gt; やら &lt;code&gt;.zshenv&lt;/code&gt; やらに書いておけば大丈夫です:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;export VAGRANT_HOME=/Volumes/data/.vagrant.d&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="docker-machine"&gt;Docker Machine&lt;/h2&gt;
&lt;p&gt;Docker Machine用のファイルもデカいので移動させたいです。&lt;/p&gt;
&lt;p&gt;Docker Machineでは &lt;code&gt;MACHINE_STORAGE_PATH&lt;/code&gt; という環境変数を参照しています。
デフォルトは &lt;code&gt;~/.docker/machine&lt;/code&gt; です。&lt;/p&gt;
&lt;p&gt;Vagrantの場合と同じように既存のファイルを新しい場所に移動し、
VB上で除去→追加の手順を踏みます。
そして以下のようなコマンドで環境変数をセットします:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;export MACHINE_STORAGE_PATH=/Volumes/data/.docker/machine&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;これも &lt;code&gt;.bashrc&lt;/code&gt; やらに書いておきましょう。&lt;/p&gt;
&lt;h2 id="注意-外部ストレージのフォーマット"&gt;注意: 外部ストレージのフォーマット&lt;/h2&gt;
&lt;p&gt;自分の場合、SDカードが元々フォーマットされていて、
差すだけで既に利用できたので、フォーマットについては特に気にせず移行作業をしてしまいました。&lt;/p&gt;
&lt;p&gt;ところが、移行後に &lt;code&gt;'docker-machine&lt;/code&gt; が謎のエラーで使えなくなってしまいました。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-D&lt;/code&gt; を付けてデバッグ情報を表示したとろ、以下のようなエラーが出ていました:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0777 for &amp;#39;/Volumes/data/.docker/machine/machines/default/id_rsa&amp;#39; are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key &amp;#34;/Volumes/data/.docker/machine/machines/default/id_rsa&amp;#34;: bad permissions
debug2: we did not send a packet, disable method
debug1: No more authentication methods to try.
Permission denied (publickey,password,keyboard-interactive).
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;実は、 &lt;strong&gt;SDカードがexFATでフォーマットされていたため、permissionが777になってしまっていた&lt;/strong&gt;
ことが原因でした。
exFATの場合、 &lt;code&gt;chmod&lt;/code&gt; することも出来ないので、フォーマットを変更する必要があります。&lt;/p&gt;
&lt;p&gt;Mac OS X用拡張ストレージは、 &lt;strong&gt;〈OS X 拡張 (ジャーナリング)〉でフォーマット&lt;/strong&gt; しましょう。
また、この際に &lt;strong&gt;〈大文字／小文字を区別する〉は不要&lt;/strong&gt; です。
OS Xのメインストレージでは区別されませんし、
Adobeなど一部の製品は大文字小文字を区別するファイルシステムをサポートしていません&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;。
無用なトラブルを避けるためにも、注意しましょう。&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;
&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description></item><item><title>早朝ランニングしたりカナヘイカフェに行ってきた日</title><link>https://www.yewton.net/2016/02/16/diary/</link><pubDate>Tue, 16 Feb 2016 23:00:00 +0900</pubDate><guid>https://www.yewton.net/2016/02/16/diary/</guid><description>&lt;h2 id="ランニング"&gt;ランニング&lt;/h2&gt;
&lt;p&gt;昨日おとといと、春が来たのかと思うくらい暖かったので、
何となく意識が高まって「よし明日からランニングを始めるぞ」という気持ちになっていた。&lt;/p&gt;
&lt;p&gt;せっかくだから一番いいランニングをしようと思って調べると、
朝食前に20分以上走るのが痩せるには最も効果があるという情報を得た。
時間を気にしながら走るのは辛そうだったので、とにかく目標地点まで行って帰ってくることにし、
スカイツリーくらいまで走ると距離的にちょうどよさそうだったのでそこを目標地点とした。&lt;/p&gt;
&lt;p&gt;そんな調査を前日に行なっていざ、走ろうと外に出ると &lt;strong&gt;滅茶苦茶寒い&lt;/strong&gt; 。
いや、昨日おとといと比較すると寒くなるというのは知っていたけれど、
走ってるうちに体あったまるだろくらいに考えていた。
ところが、走れども走れども一向に体は暖まらず、手はかじかみ、
寒さに震えながら走ることになった。&lt;/p&gt;
&lt;p&gt;後で調べたらその時の気温が3度とかだったので、そりゃ、寒いワケだ、と。&lt;/p&gt;
&lt;p&gt;寒さを舐めてはいけない。
次はもっと防寒するか、もっと暖かい日にしよう、という学びを得た。&lt;/p&gt;
&lt;h2 id="カナヘイのゆるっとカフェ"&gt;カナヘイのゆるっとカフェ&lt;/h2&gt;
&lt;p&gt;仕事終わりに、&lt;a href="http://kanahei.blog.jp/archives/1049325539.html" target="_blank" rel="noopener"&gt;カナヘイのゆるっとカフェ&lt;/a&gt;に行ってきた
(カフェ公式ページは無くて、イベントページの1コンテンツという感じだったので、カナヘイさんのブログ記事にリンク)。&lt;/p&gt;
&lt;iframe src="https://drive.google.com/file/d/0B4XWl5W7tB7IQ09Jc3dKcmN6OEk/preview" width="320" height="240"&gt;&lt;/iframe&gt;
&lt;p&gt;こんな感じでパルコ入口で待ち構えている。&lt;/p&gt;
&lt;iframe src="https://drive.google.com/file/d/0B4XWl5W7tB7IMzJrYllaRmo5dUk/preview" width="320" height="240"&gt;&lt;/iframe&gt;
&lt;p&gt;7階に辿り着くと、巨大うさぎ&amp;amp;ピスケがお出迎え。
これ、多分カナヘイの個展でも使われてた奴らが着替えただけだ。&lt;/p&gt;
&lt;p&gt;その他の最高に可愛い写真は&lt;a href="https://drive.google.com/folderview?id=0B4XWl5W7tB7IcEpEdWVPQm5HWkk&amp;amp;usp=drive_web" target="_blank" rel="noopener"&gt;こちら&lt;/a&gt;
に置いてあるのでどうぞご自由にご利用下さい。&lt;/p&gt;
&lt;p&gt;もう、本当に最高にゆるっとして可愛くて可笑しくて、また行くことが確定した。
グッズ込みで1万超の出費だったけど何も痛くないね!!&lt;/p&gt;
&lt;p&gt;カナヘイさんもっとイベントやってください。&lt;/p&gt;
&lt;h2 id="google-drive-の画像を-web-ページに埋め込む"&gt;Google Drive の画像を Web ページに埋め込む&lt;/h2&gt;
&lt;p&gt;カナヘイカフェの記事を書こうとして、どうにか写真を埋め込めないか色々調べたら、
どうも写真の単体ページ(&lt;a href="https://drive.google.com/file/d/0B4XWl5W7tB7IQ09Jc3dKcmN6OEk/view" target="_blank" rel="noopener"&gt;こういうの&lt;/a&gt;)を開いて、
〈アイテムを埋め込む〉というのが真っ当な手段ぽかった。&lt;/p&gt;
&lt;p&gt;直リンクする方法もあるみたいだけど、いつ Google 様に殺されるか分からなかったので止めておく。&lt;/p&gt;</description></item><item><title>Hugoの記事をようやく書き上げた日</title><link>https://www.yewton.net/2016/02/14/diary/</link><pubDate>Sun, 14 Feb 2016 00:26:33 +0900</pubDate><guid>https://www.yewton.net/2016/02/14/diary/</guid><description>&lt;p&gt;たまには人類に少しでも役に立つような記事も書こうと思い、
&lt;a href="https://www.yewton.net/2016/02/02/blog-with-hugo/" target="_blank" rel="noopener"&gt;Hugoの記事&lt;/a&gt;を書いていた。&lt;/p&gt;
&lt;p&gt;自分が通しでやったことだし、すぐ書き上がるだろーと高をくくっていたら、
なんだかんだ書き始めてから2週間くらい経ってしまった(もちろん、そればかりやってたワケじゃないけど)。
自分の遅筆さに呆れるばかりである。&lt;/p&gt;
&lt;p&gt;普段から余り人様に見せられるような文章を書いていない、というのが露呈した気がした。
そういえば普段の会話もあまり賢いものとは言えない…。
時を経るごとに、喋るのも下手になっていると感じる。&lt;/p&gt;
&lt;p&gt;やばいなー。やばいヤバイ。&lt;/p&gt;
&lt;p&gt;人とコミュニケーションとらずに生きていくのにそろそろ限界を感じているので、
意図して真っ当な会話をし、文章を書けるように心がけていこうと思う。
そういえば最近まともに読書もしていないし…。
社会生活を営む人間として真っ当に生きていく為の読書くらいは、しよう。&lt;/p&gt;
&lt;h2 id="業務外のアレコレ"&gt;業務外のアレコレ&lt;/h2&gt;
&lt;p&gt;最近(ほぼ)趣味で、 AWS上にシンプルに構築されたWordPressブログを、
HTTPSにしてついでにHTTP/2対応してHHVMで稼動させようぜ、というような試みをしている。&lt;/p&gt;
&lt;p&gt;AWSは最近ようやく触りはじめたばかりなので、
どういったことが出来るのか、から調べつつやっている。&lt;/p&gt;
&lt;p&gt;ベースがAmazonLinuxなので、HHVMは公式にサポートされていない。
なので Docker を利用したいところなのだけれど、
WordPress がダイナミックに自分自身を更新するという話を聞いて、うーん、となった。
HHVMだけをECSで動かしてもしょうがないから、やるならWordPressもコンテナに詰めるのだけど、
コンテナ内で稼動しているWordPressを更新してもしょうがない、というかコンテナ再起動したら消えちゃうしなー、という。
それとも、ECSで使うEC2インスタンスにWordPressを普通に入れちゃえばいいのかな？&lt;/p&gt;
&lt;p&gt;などなど、色々試行錯誤の日々である。
今日はHugoの記事書き上げるのとドメイン移行でいっぱいいっぱいだったので、
明日には何らかの成果を出したい…。&lt;/p&gt;</description></item><item><title>Hugo + GitHub Pages でお手軽にブログを始めよう</title><link>https://www.yewton.net/2016/02/02/blog-with-hugo/</link><pubDate>Tue, 02 Feb 2016 18:44:21 +0900</pubDate><guid>https://www.yewton.net/2016/02/02/blog-with-hugo/</guid><description>&lt;p class="mylastmod"&gt; 13, 2020 最終更新&lt;/p&gt;
&lt;div class="callout flex px-4 py-3 mb-6 rounded-md border-l-4 bg-blue-100 dark:bg-blue-900 border-blue-500"
data-callout="note"
data-callout-metadata=""&gt;
&lt;span class="callout-icon pr-3 pt-1 text-blue-600 dark:text-blue-300"&gt;
&lt;svg height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&gt;&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="m16.862 4.487l1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8l.8-2.685a4.5 4.5 0 0 1 1.13-1.897zm0 0L19.5 7.125"/&gt;&lt;/svg&gt;
&lt;/span&gt;
&lt;div class="callout-content dark:text-neutral-300"&gt;
&lt;div class="callout-title font-semibold mb-1"&gt;Note&lt;/div&gt;
&lt;div class="callout-body"&gt;&lt;p&gt;2020年1月現在は、
。&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="はじめに"&gt;はじめに&lt;/h2&gt;
&lt;p&gt;この記事は「いい感じのブログを無料で手軽に作れないかなー」、と思っている人が主な対象です。&lt;/p&gt;
&lt;p&gt;〈いい感じ〉というのが抽象的ですが、以下のような欲求をイメージしています:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
にあるような静的サイトジェネレータがいい&lt;/li&gt;
&lt;li&gt;サイト生成は速ければ速いほどいい&lt;/li&gt;
&lt;li&gt;モダンでレスポンシブルなのがいい&lt;/li&gt;
&lt;li&gt;記事を書いたら即確認出来るのがいい&lt;/li&gt;
&lt;li&gt;GitHub Pagesに簡単にデプロイ出来るのがいい&lt;/li&gt;
&lt;li&gt;独自ドメインは使いたい&lt;/li&gt;
&lt;li&gt;ブログにありがちなコメント機能とかアクセス解析とかが出来るといい&lt;/li&gt;
&lt;li&gt;HTTPSなのがいい&lt;/li&gt;
&lt;li&gt;HTTP/2なのがいい&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="サイトの方式を考える"&gt;サイトの方式を考える&lt;/h2&gt;
&lt;p&gt;手軽に始めたいので、準備はなるべく少ない方が嬉しいですね。&lt;/p&gt;
&lt;p&gt;WordPress みたいな動的な方式はサーバを用意しないといけないので手間ですし、場合によっては金もかかります。&lt;/p&gt;
&lt;p&gt;一方の静的サイト配信であれば、必要なのは HTML を配信出来る場所だけです。
GitHub Pages や類似のサービスを使えば無料で利用できますね。&lt;/p&gt;
&lt;h2 id="静的サイトジェネレータを選ぶ"&gt;静的サイトジェネレータを選ぶ&lt;/h2&gt;
&lt;p&gt;というわけで静的サイトを作成するためのジェネレータを選びます。&lt;/p&gt;
&lt;p&gt;
の中から適当に選びましょう。&lt;/p&gt;
&lt;p&gt;
や
はメジャーっぽいですが検索してみると、何だか遅いみたいです(使ったことない)。&lt;/p&gt;
&lt;p&gt;
はドキュメントを書くのには向いています(自分も利用しています)。ですがブログを書くためのものではありません。&lt;/p&gt;
&lt;p&gt;
か
あたりがよさそうです。
これら二つはコンセプトもよく似ているし、最早好みの世界ですね。自分は何となく Hugo を使っています。&lt;/p&gt;
&lt;h2 id="hugo"&gt;Hugo&lt;/h2&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://www.yewton.net/media/2016-01-11_184419/hugo.png" alt="Hugoのロゴ" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;
は超高速でシンプルかつ柔軟な静的サイトジェネレータだそうです。
Go言語で書かれていて、インストールはとってもカンタン。すぐに使えます。&lt;/p&gt;
&lt;p&gt;使い方もとってもカンタン…というワケではないかもしれません。
といっても、それは Hugo が殊更難しいというワケではなく、
そもそも静的サイトジェネレーターというモノを理解している必要がある、ということだと思います。&lt;/p&gt;
&lt;p&gt;ブログを書く、ということだけに目的を絞れば、覚える必要がある用語は
&lt;em&gt;Content&lt;/em&gt;, &lt;em&gt;Themes&lt;/em&gt;, &lt;em&gt;Taxonomies&lt;/em&gt; の3つだけです。&lt;/p&gt;
&lt;h3 id="content"&gt;Content&lt;/h3&gt;
&lt;p&gt;ブログで言えば記事のことです。&lt;/p&gt;
&lt;p&gt;Content がどのように表示されるかは使用しているテーマによりますが、
ブログ用テーマのほとんどは &lt;code&gt;post&lt;/code&gt; ディレクトリ以下にあるファイルを記事として扱うようです。&lt;/p&gt;
&lt;h3 id="themes"&gt;Themes&lt;/h3&gt;
&lt;p&gt;そのまま、サイトに適用するテーマです。&lt;/p&gt;
&lt;p&gt;Hugoの場合、テーマはそのサイトの構成まで決めてしまいます。
独自にテンプレートを書くことでカスタマイズ出来るとはいえ、目的に沿ったテーマを選択するのが無難です。&lt;/p&gt;
&lt;p&gt;テーマ選択の方法については後述します。&lt;/p&gt;
&lt;h3 id="taxonomies"&gt;Taxonomies&lt;/h3&gt;
&lt;p&gt;やけに難しい単語ですが、分類方法のことです。
ブログなら &lt;strong&gt;カテゴリ&lt;/strong&gt; や &lt;strong&gt;タグ&lt;/strong&gt; といった類のものです。&lt;/p&gt;
&lt;p&gt;幸い、カテゴリとタグによる基本的な分類であればデフォルトで対応しているため、あまり意識する必要はありません。
カテゴリやタグのことを Taxonomies と呼ぶことだけ押さえておけばOKです。&lt;/p&gt;
&lt;h2 id="サイトを作る"&gt;サイトを作る&lt;/h2&gt;
&lt;p&gt;早速サイトを作っていきましょう。&lt;/p&gt;
&lt;p&gt;
に従えば基本的に迷うことは無いと思います。
ここでは、適当にサイトを作って、ひとつ記事を書いてみて、それがブラウザで確認出来るようになれば大丈夫です。&lt;/p&gt;
&lt;p&gt;ただし、 &lt;strong&gt;日本語に対応させる設定は追加で必要&lt;/strong&gt; です。&lt;/p&gt;
&lt;h3 id="日本語対応"&gt;日本語対応&lt;/h3&gt;
&lt;p&gt;ありがたいことに、Hugoは日本語や中国語の為の特別な設定を用意してくれています。
設定ファイルに &lt;code&gt;hasCJKLanguage = true&lt;/code&gt; という行を追加しましょう。&lt;/p&gt;
&lt;p&gt;これをやらないと、一覧用に記事を自動で切り詰めてくれる機能や、
読み終えるまでの予想時間の計算が滅茶苦茶になってしまいます。&lt;/p&gt;
&lt;h2 id="テーマを決める"&gt;テーマを決める&lt;/h2&gt;
&lt;p&gt;次はサイトに適用するテーマを選択しましょう。&lt;/p&gt;
&lt;p&gt;
で実際の例を見ながらテーマを選ぶことが出来ます。
ブログ用のテーマのみに絞って見たい場合は
からどうぞ。&lt;/p&gt;
&lt;p&gt;注意点として、Hugoには記事を読み終えるまでの時間やおおよその文字数を表示する機能が組込まれているのですが、テーマがサポートしていない場合は表示されません。
このような機能を使いたい場合は、テーマでサポートされているかを確認しましょう。&lt;/p&gt;
&lt;p&gt;このサイトは
を使っています。
ショーケースの中では使える機能が一番多いと思うので、どういうことが出来るのか知るには丁度よいテーマだと思います。&lt;/p&gt;
&lt;h2 id="favicon-を置こう"&gt;favicon を置こう&lt;/h2&gt;
&lt;p&gt;デフォルトでは Hugo の favicon が表示されてしまうので、カスタマイズしましょう。
などを使うとよいです。&lt;/p&gt;
&lt;p&gt;生成した &lt;code&gt;.ico&lt;/code&gt; ファイルを &lt;code&gt;static&lt;/code&gt; 直下に配置すればOKです。&lt;/p&gt;
&lt;h2 id="記事を書く"&gt;記事を書く&lt;/h2&gt;
&lt;p&gt;記事はMarkdownで書きます。&lt;/p&gt;
&lt;p&gt;ここで困るのは、Markdownにもいくつか方言があることです。
何を参考に書けばいいか迷ってしまいますね。&lt;/p&gt;
&lt;p&gt;HugoではMarkdownの処理に
を使っています。
Blackfriday特有の書式(脚注など)もある為、こちらを参照しながら書くとよいでしょう。&lt;/p&gt;
&lt;h3 id="記事のファイル名について"&gt;記事のファイル名について&lt;/h3&gt;
&lt;p&gt;日記や思い付きで即興で記事を書く場合、いちいち被らないようにファイル名を考えるのは面倒ですよね。&lt;/p&gt;
&lt;p&gt;Hugoの場合ファイル名は管理上の問題でしかないので、適当に日付やタイムスタンプでも入れておけばよいです。
デフォルトではファイル名がURLに使われますが、記事毎の設定で &lt;code&gt;slug = &amp;quot;hogehoge&amp;quot;&lt;/code&gt; のように設定しておけば、
実際のURLは &lt;code&gt;/post/hogehoge&lt;/code&gt; のようになります。&lt;/p&gt;
&lt;p&gt;また、以下のように設定ファイルに書いておけば、年月日がURLのプレフィクスに付くので被る心配もありません:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[permalinks]
post = &amp;#34;/:year/:month/:day/:slug&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="コメント対応"&gt;コメント対応&lt;/h2&gt;
&lt;p&gt;なんとなくコメント欄があるとオープンな感じでいいですよね？
ということでコメントにも対応させてみましょう。&lt;/p&gt;
&lt;p&gt;Hugo自身が
ので、
を使いましょう。
ただし、Disqusによるコメント対応も、テーマによってはサポートされていない場合があるので要注意です。&lt;/p&gt;
&lt;p&gt;何よりもまず Disqus への登録です。
を見ながら行いましょう。
設定は特に必要ありませんので登録だけ済ませれば一旦OKです。後から言語設定を日本語にしたりすることも出来ます。&lt;/p&gt;
&lt;p&gt;登録が完了したら、登録時に入力した shortname (unique Disqus URL) を以下のように設定に追記しましょう:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;disqusShortname = &amp;#34;sitename&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;これだけでHugoの設定は完了です。(テーマが対応していれば)個別の記事ページにコメント欄が出現します。&lt;/p&gt;
&lt;h2 id="デプロイ"&gt;デプロイ&lt;/h2&gt;
&lt;p&gt;生成したブログは GitHub Pages でホスティングします。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;gh-pages&lt;/code&gt; ではなく、ユーザや Organization のページとして公開する場合は、
に
何も考えずに従えばOKです。
例示されているスクリプトもそのままコピペで使えます。&lt;/p&gt;
&lt;p&gt;実際にこのブログで使われているモノは全て
にあるので参考にしてください。&lt;/p&gt;
&lt;h2 id="独自ドメイン対応"&gt;独自ドメイン対応&lt;/h2&gt;
&lt;p&gt;github.com ドメインでホスティングするだけでよければ、ここから先の作業は不要です。おめでとうございます。&lt;/p&gt;
&lt;p&gt;以降はHugoとは関係ない話が続きます。&lt;/p&gt;
&lt;p&gt;既に独自ドメインを持っていて、それをブログでも使いたい場合は、
の設定をGitHub上で行う必要があります。
を作ってあげて、
DNSレジストラ側で &lt;code&gt;CNAME&lt;/code&gt; とか &lt;code&gt;ANAME&lt;/code&gt; の設定を行ないます。&lt;/p&gt;
&lt;h3 id="サブドメイン-vs-ルートドメイン"&gt;サブドメイン vs ルートドメイン&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;CNAME&lt;/code&gt; の設定をするか &lt;code&gt;ANAME&lt;/code&gt; の設定をするかは、サブドメインを使うかルートドメインを使うかの違いです。
GitHubのヘルプによると、
そうです。&lt;/p&gt;
&lt;p&gt;サブドメインを推奨する理由は以下のようです:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GitHubのCDNの恩恵を受けられる&lt;/li&gt;
&lt;li&gt;GitHub自体のIPアドレス変更に影響を受けない&lt;/li&gt;
&lt;li&gt;DoS対策がより効率的になるのでページロードが高速になる&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;というわけで、特別な事情がない限りはサブドメインを利用するのがよいでしょう&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;
&lt;h2 id="https化"&gt;HTTPS化&lt;/h2&gt;
&lt;p&gt;ここまででブログとしての体裁は整いました。
ですが、折角つくったサイトですからHTTPSで配信したいですよね？しましょう。&lt;/p&gt;
&lt;p&gt;これには
を利用出来ます。
が非常に参考になります。&lt;/p&gt;
&lt;p&gt;設定が反映されるまでは最長1日程度かかりますので、ゆっくりと待ちましょう。&lt;/p&gt;
&lt;p&gt;なおCloudFlareを利用すると、ついでに HTTP/2 も有効になります。
他にもJSの軽量化などの各種高速化の設定を利用出来ますので、設定項目を見てみるのもよいでしょう。&lt;/p&gt;
&lt;h3 id="注意"&gt;注意&lt;/h3&gt;
&lt;p&gt;注意点として、この際に Flexible SSL を用いる場合は、あくまでユーザとCloudFlare間の通信が暗号化されるだけで、 &lt;strong&gt;CloudFlareとGitHub Pages間の通信は暗号化されていません&lt;/strong&gt; 。
後者の間の通信は改竄されうる状態で、かつ、ユーザはそれを知る術が無いという状態に…。&lt;/p&gt;
&lt;p&gt;
に詳しく書かれていますが、
一応そういう状態であるということは認識しておきましょう。&lt;/p&gt;
&lt;h2 id="終わりに"&gt;終わりに&lt;/h2&gt;
&lt;p&gt;いい感じのブログを無料で手軽に作る方法についてまとめました。
改めてまとめてみるとそれなりにボリュームがあってちょっと大変でした…。&lt;/p&gt;
&lt;p&gt;これからブログを始めるぞーと思っている誰かの役に立てばいいなーと思います。&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;こう書いている自分も、最初は特に気にせずにルートドメインで登録してしまっていました。この記事を書きながら気づいて、慌てて &lt;code&gt;www&lt;/code&gt; サブドメインに移行しました。&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description></item><item><title>スクラム入門を翻訳する日々</title><link>https://www.yewton.net/2016/01/31/diary/</link><pubDate>Sun, 31 Jan 2016 23:18:29 +0900</pubDate><guid>https://www.yewton.net/2016/01/31/diary/</guid><description>&lt;p&gt;最近、&lt;a href="https://www.gitbook.com/book/yewton/scrumprimer/details" target="_blank" rel="noopener"&gt;スクラム入門の翻訳&lt;/a&gt;を
細々とやっている。&lt;/p&gt;
&lt;p&gt;元々は&lt;a href="https://www.scrumprimer.org/" target="_blank" rel="noopener"&gt;Scrum Primer - Short Introduction to Scrum&lt;/a&gt;で配布されているPDFで、
認定スクラムマスター研修でも参照される真っ当な文献(のはす)。&lt;/p&gt;
&lt;p&gt;日本語版があるにはある&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;んだけれど、古いし翻訳の質が怪しいので、
自分の理解を進めるという意味も含めて独力で翻訳してみることにした。&lt;/p&gt;
&lt;p&gt;進捗としては、1週間の空いた時間をほぼそればっかりに費してようやっと 1/5 くらい進んだ。
さすがに他のこともやりたいので、完成までは2ヶ月くらいかかってしまうかもしれない…。
3月中には終わるように頑張ろう。&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;すくすくスクラムが翻訳した版がある。あるはずなのだけれど公式に配布している所が見当たらない。&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description></item><item><title>hugo.elを書いた</title><link>https://www.yewton.net/2016/01/26/hugo-el/</link><pubDate>Tue, 26 Jan 2016 23:25:40 +0900</pubDate><guid>https://www.yewton.net/2016/01/26/hugo-el/</guid><description>&lt;h2 id="とは"&gt;#とは&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/yewton/hugo.el" target="_blank" rel="noopener"&gt;hugo.el&lt;/a&gt;は、Hugoでサイト作成する際に便利な関数群を定義したパッケージ。
&lt;a href="https://marmalade-repo.org/" target="_blank" rel="noopener"&gt;marmalade-repo&lt;/a&gt;で公開されているので、パッケージの設定をすれば簡単にインストール出来るハズ。&lt;/p&gt;
&lt;h2 id="作った動機"&gt;作った動機&lt;/h2&gt;
&lt;p&gt;何か〈物を書く〉という作業をする時、自分はEmacsを使っていて、可能な限りEmacsの中から出たくない。
HugoはCLIのインタフェースなので、ターミナルとEmacsを行き来することになってしまうのは辛い。&lt;/p&gt;
&lt;p&gt;あと色んなテーマを試したい時に、いちいちテーマ名をコピペする必要があり、辛かった。
一覧の中からhelmで選択したかった。&lt;/p&gt;
&lt;p&gt;…というように、Emacsの中で色々作業が完結するようにしたかった。&lt;/p&gt;
&lt;h2 id="作ってみて"&gt;作ってみて&lt;/h2&gt;
&lt;p&gt;正直テーマのインストール補助機能はHugoを初めて触って、色々試してみたいフェーズでしか使わないので、
ほとんどの場合大した価値じゃないかもしれない。&lt;/p&gt;
&lt;p&gt;個人的には、 &lt;code&gt;hugo-new-content&lt;/code&gt; と、 &lt;code&gt;hugo-start-server&lt;/code&gt;, &lt;code&gt;hugo-open-browser&lt;/code&gt; が中々便利だなーと思って使っている。
適当に記事を書き始められるし、プレビューするためにターミナルで確認したアドレスをブラウザに打ち込むとかやらなくてよいので。&lt;/p&gt;
&lt;p&gt;書き終えたあとに &lt;code&gt;hugo-deploy&lt;/code&gt; でひょいっと公開出来るのも地味に便利。
ただ、デプロイスクリプトを呼び出してるだけなんだけどね…。&lt;/p&gt;
&lt;p&gt;普段Emacsで物書きをするひとで、Hugoでブログ書こうと思う人は是非便利に使ってもらいたい。
そんな人あんまりいなさそうだけど…。&lt;/p&gt;
&lt;h2 id="todo"&gt;TODO&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;hugo-open-browser&lt;/code&gt; で今開いているcontentを直接開けたらより便利かもしれない&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hugo-deploy&lt;/code&gt; が同期処理になってて固まるので、非同期にする&lt;/li&gt;
&lt;li&gt;テスト全然書いてないので、テストを書いてバッジをつけて喜ぶ&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>JIRA Agile用のuserscriptを作ったりした日</title><link>https://www.yewton.net/2016/01/23/diary/</link><pubDate>Sat, 23 Jan 2016 23:47:43 +0900</pubDate><guid>https://www.yewton.net/2016/01/23/diary/</guid><description>&lt;h2 id="趣味の政策物"&gt;趣味の政策物&lt;/h2&gt;
&lt;p&gt;弊チームではバックログとしてJIRAを使っている。&lt;/p&gt;
&lt;p&gt;ここ最近しつこく「管理者権限が欲しいなァ〜(ﾁﾗｯ」としていたらめでたく権限を付与してもらえたので、
ここぞとばかりにJIRAをカスタムして使いやすいようにしていた。&lt;/p&gt;
&lt;p&gt;ワークフローを単純にしたり、使わないフィールドを非表示にしたり、
これまで説明文用のテンプレからコピペしたりしていたのを、それぞれ専用のフィールドを設けたり。&lt;/p&gt;
&lt;p&gt;色々準備はしたもの、やはり始まってみると色々不便なところが出てきて、
しかもJIRAの設定じゃどうしようもない部分もあったりする。&lt;/p&gt;
&lt;p&gt;たかがツール、されどツールで、ツールに使われているようじゃ到底円滑にスプリントを回すことなんて出来ない。&lt;/p&gt;
&lt;p&gt;そこで、スクラムマスターがセレモニーを進めやすいように支援するためのuserscriptを書いた。
ソースは&lt;a href="https://github.com/yewton/userscripts" target="_blank" rel="noopener"&gt;yewton/userscripts&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id="component-labels-for-jira-scrum"&gt;Component-labels for JIRA Scrum&lt;/h3&gt;
&lt;p&gt;コンポーネントをエピックのようにスクラムボード上で分かりやすいく表示する。&lt;/p&gt;
&lt;p&gt;ラベリングをしたいが為だけにエピックを使ってしまうという事態は結構そこかしこで起こっているみたいだった。
本来はコンポーネントでやるべきもので、エピックはエピックとして使えるのが健全な状態だと思うので、作った。&lt;/p&gt;
&lt;p&gt;実装は滅茶苦茶単純で、DOMに変更がある度に全課題を舐めて、未設定だったらAPIで該当する課題のコンポーネントを取得している。
なので、バックログに積まれている課題数分、ページを開いた瞬間にリクエストが走ることになる。
リクエストの仕方を何か工夫しないと使いものにならないかなーと思っていたのだけれど、
案外数百リクエスト飛ばすぐらいだとビクともしなかったので、愚直な実装のまま。&lt;/p&gt;
&lt;h3 id="detail-pop-up-for-jria-scrum"&gt;Detail Pop-up for JRIA Scrum&lt;/h3&gt;
&lt;p&gt;各課題に詳細画面をポップアップで開くためのボタンを追加する。&lt;/p&gt;
&lt;p&gt;アジャイルボードではカスタムフィールドが表示されないので、
確認するためには編集ポップアップを開くか、詳細画面に飛ぶしかなかった。
しかも、アクティブなスプリント中はクローズされている課題が編集出来ないので、
前者の方法はスプリントレビュー時には使えない。&lt;/p&gt;
&lt;p&gt;画面遷移せずに詳細画面が開ければ用は足りると考え、
&lt;a href="https://www.ericmmartin.com/projects/simplemodal/" target="_blank" rel="noopener"&gt;SimpleModal&lt;/a&gt;という、
その名の通りシンプルなモーダル機能を実装するためのライブラリを使って、
&lt;code&gt;iframe&lt;/code&gt; で詳細画面を開くだけの機能を追加した。&lt;/p&gt;
&lt;h2 id="第3回-実践的ドメイン駆動設計ワークショップ---connpass"&gt;&lt;a href="https://ddd-alliance.connpass.com/event/24672/" target="_blank" rel="noopener"&gt;第3回 実践的ドメイン駆動設計ワークショップ - connpass&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;参加してきた。&lt;/p&gt;
&lt;p&gt;エンジニアチームとして、業務と技術両面でどういう風に学んでいけばいいかっていう話と、
実際にやってみたら、コードの雰囲気はこんな感じだぜ、っていう話。&lt;/p&gt;
&lt;p&gt;ドメイン層のクラスが1,000個とかあって、個々のクラスは 30 〜 60 行が大半を占めるそう。
目指すべき方向はそこだっていうのはわかってはいるけど、
実際に稼動してるプロダクトの数字っていうのは説得力がある。&lt;/p&gt;
&lt;p&gt;ドメイン駆動設計を実践するなら、ドメインエキスパートとか、企画者との協調が必須だと思うのだけれど、
それをどうプロセスとして制御可能な形で行えばいいか、あまり掴めてない。&lt;/p&gt;
&lt;p&gt;会話を重視しつつ、かつダラダラやらずに予測可能な状態で、
モデルに関する会話をする場を、開発プロセスのどこで行えばいいんだろう。&lt;/p&gt;
&lt;p&gt;増田さんに上手いやり方無いっすか、と相談してみたけれど、
いい方法っていうのはなくて、エンジニアチームが実績を積み重ねて信頼を得ていって、
協力体制を築くしかないね、ということだった。
それでも駄目なら、職場を変えよ、とも。&lt;/p&gt;
&lt;p&gt;色々仰々しいプロセスやツールを導入せずとも、
いつか阿吽の呼吸で、エンジニアチームと企画陣が協調して最高の仕事が出来るようになったときが、
アジャイルでドメイン駆動な状態なんだろう、たぶん。適当。&lt;/p&gt;</description></item><item><title>markdown-modeでSKKの変換確定するためにRETするとカーソルが行頭に飛ぶ問題の回避策</title><link>https://www.yewton.net/2016/01/20/markdown-mode-skk-kakutei/</link><pubDate>Wed, 20 Jan 2016 22:40:16 +0900</pubDate><guid>https://www.yewton.net/2016/01/20/markdown-mode-skk-kakutei/</guid><description>&lt;p&gt;markdown-mode 2.1 で SKK 15.2 使ってると、確定しようと思って &lt;code&gt;&amp;lt;return&amp;gt;&lt;/code&gt; すると、
確定後にカーソルが行頭に飛んでしまうという問題に遭遇した。
&lt;code&gt;C-j&lt;/code&gt; で確定する場合は起こらない。&lt;/p&gt;
&lt;h2 id="tldr"&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;以下を &lt;code&gt;init.el&lt;/code&gt; 相当のファイルに書けば回避出来る。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-lisp" data-lang="lisp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;my--markdown-entery-key-ad&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;this-func&lt;/span&gt; &lt;span class="k"&gt;&amp;amp;rest&lt;/span&gt; &lt;span class="nv"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;markdown-modeでskk-henkan-mode中にエンターすると行頭にカーソルが飛んでしまう問題の対応&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nv"&gt;skk-henkan-mode&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;skk-kakutei&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt; &lt;span class="nv"&gt;this-func&lt;/span&gt; &lt;span class="nv"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;advice-add&lt;/span&gt; &lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;markdown-enter-key&lt;/span&gt; &lt;span class="ss"&gt;:around&lt;/span&gt; &lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;my--markdown-entery-key-ad&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="原因解明に至るまで"&gt;原因解明に至るまで&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;return&amp;gt;&lt;/code&gt; = &lt;code&gt;&amp;lt;C-m&amp;gt;&lt;/code&gt; では起こり、&lt;code&gt;C-j&lt;/code&gt; では起こらないので、まずはキーバインドを確認したところ、
前者は &lt;code&gt;markdown-enter-key&lt;/code&gt; という関数が割り当てられていた。&lt;/p&gt;
&lt;p&gt;実装は至ってシンプルだった:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-lisp" data-lang="lisp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;markdown-enter-key&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;Handle RET according to to the value of `markdown-indent-on-enter&amp;#39;.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;interactive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;newline&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;when&lt;/span&gt; &lt;span class="nv"&gt;markdown-indent-on-enter&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;markdown-indent-line&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;次に &lt;code&gt;trace-function&lt;/code&gt; で &lt;code&gt;markdown-enter-key&lt;/code&gt; と &lt;code&gt;skk-kakutei&lt;/code&gt; をトレースしたところ、
以下のような出力が得られた:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;1 -&amp;gt; (markdown-enter-key)
| 2 -&amp;gt; (skk-kakutei)
| 2 &amp;lt;- skk-kakutei: nil
1 &amp;lt;- markdown-enter-key: nil
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;markdown-enter-key&lt;/code&gt; が発動して &lt;code&gt;(newline)&lt;/code&gt; が評価された結果、
&lt;code&gt;skk-kakutei&lt;/code&gt; が発動して変換確定、その後に &lt;code&gt;markdown-indent-line&lt;/code&gt; が呼ばれているのがどうも悪いらしい。&lt;/p&gt;
&lt;h2 id="回避方法"&gt;回避方法&lt;/h2&gt;
&lt;p&gt;これは &lt;strong&gt;&lt;code&gt;markdown-enter-key&lt;/code&gt; が呼ばれた時に &lt;code&gt;skk-henkan-mode&lt;/code&gt; 中だったら、&lt;/strong&gt;
&lt;strong&gt;本来の挙動ではなく &lt;code&gt;skk-kakutei&lt;/code&gt; だけを行なうようにする&lt;/strong&gt; ことで回避出来そうだ。&lt;/p&gt;
&lt;p&gt;こういう部分的な挙動の修正には advice を使うといい。
というわけで前述の挙動をそのまま定義すると、冒頭のようなコードになる。&lt;/p&gt;</description></item><item><title>雪が振ったので一日中家に引き込もっていた日の次の日</title><link>https://www.yewton.net/2016/01/19/diary/</link><pubDate>Tue, 19 Jan 2016 23:00:00 +0900</pubDate><guid>https://www.yewton.net/2016/01/19/diary/</guid><description>&lt;p&gt;昨日は都内も大雪(いうほどか？)で出社がダルそうだったので、終日リモートワークしていた。
本当に一歩も家から出ずに、パジャマから着替えもせずに、もくもくとPC作業。&lt;/p&gt;
&lt;h2 id="個人のタスク管理"&gt;個人のタスク管理&lt;/h2&gt;
&lt;p&gt;最近認定スクラムマスターも取ったし、
一日中スクラムのことばかり考えて悶々とするような続いている。&lt;/p&gt;
&lt;p&gt;そんな中で、個人的な、業務とかまったく関係ない趣味のタスク管理もなんとかしたいなぁと思いはじめた。&lt;/p&gt;
&lt;p&gt;趣味なのでそんなガッツリ管理するわけじゃないのでゆるいので何かないかなーと探したら、
&lt;a href="https://trello.com/" target="_blank" rel="noopener"&gt;Trello&lt;/a&gt; というのがいい感じにゆるゆると使えそうな感じだった。&lt;/p&gt;
&lt;p&gt;見積もりとか検証とかは出来なさそうだけど、とりあえず何もしないよりはいいだろーっていう想いで、使うことにした。&lt;/p&gt;
&lt;p&gt;ボードによると、目下最優先のタスクは、 &lt;code&gt;markdwon-mode&lt;/code&gt; で &lt;code&gt;skk-mode&lt;/code&gt; の確定キーバインドが想定通り機能しない件の対応である。
やるぞ。&lt;/p&gt;</description></item><item><title>HTTPSに対応してついでにHTTP/2対応された日</title><link>https://www.yewton.net/2016/01/18/diary/</link><pubDate>Mon, 18 Jan 2016 00:06:20 +0900</pubDate><guid>https://www.yewton.net/2016/01/18/diary/</guid><description>&lt;h2 id="https--http2-対応"&gt;HTTPS + HTTP/2 対応&lt;/h2&gt;
&lt;p&gt;世の中的にHTTPS対応してないといかんような気がしたので、
このサイトもHTTPSで配信するように対応した。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://1000ch.net/posts/2015/github-pages-custom-domain-in-https.html" target="_blank" rel="noopener"&gt;GitHub Pagesに設定しているカスタムドメインをHTTPS対応させる - 1000ch.net&lt;/a&gt;を大いに参考にさせていただいた。
もう本当に書いてある通りにすればいい。 &lt;a href="https://www.cloudflare.com/" target="_blank" rel="noopener"&gt;CloudFlare&lt;/a&gt; 様々である。&lt;/p&gt;
&lt;p&gt;敢えて付け加えるとしたら、(CloudFlareのサイト上に注記されてはいるけども)Flexible SSLが実際に動くようになるまでは結構時間がかかること。
自分の場合は、都合7〜8時間程度かかった。
この間、ステータスは &lt;code&gt;AUTHORIZING CERTIFICATES&lt;/code&gt; から &lt;code&gt;ISSUING CERTIFICATES&lt;/code&gt; になり、最終的に &lt;code&gt;ACTIVE CERTIFICATE&lt;/code&gt; になった。&lt;/p&gt;
&lt;p&gt;この方法でサイトをHTTPS対応するのは簡単だけども懸念もあるらしい&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;ので、
また今度この辺が実際どういう仕組みで動いてるのか調べてまとめたいと思う。&lt;/p&gt;
&lt;p&gt;なお、CloudFlareを利用することで副次的に HTTP/2 にも対応することになった。
Chromeで &lt;a href="https://chrome.google.com/webstore/detail/http2-and-spdy-indicator/mpbpobfflnpcgagjijhmgnchggcjblin" target="_blank" rel="noopener"&gt;HTTP/2 and SPDY indicator&lt;/a&gt;
を入れてアクセスしたりすると分かる。&lt;/p&gt;
&lt;h2 id="ddd"&gt;DDD&lt;/h2&gt;
&lt;p&gt;開発チームビルディングの一環で、ドメイン駆動設計について改めて色々調べたりしている。&lt;/p&gt;
&lt;p&gt;図やドキュメントに本質はないとはいえ、ユビキタス言語のサポートとして用語集を作ったり、
深いモデルの洞察のために図が役に立ったりするので、そのへんのサポートツールが欲しくなる。&lt;/p&gt;
&lt;p&gt;色々探してたら&lt;a href="https://skillsmatter.com/skillscasts/6259-ddd-and-microservices-at-last-some-bounderies" target="_blank" rel="noopener"&gt;エヴァンス先生がマイクロサービスとの関わりについて講習してる動画&lt;/a&gt;があった。
境界づけられたコンテキストはサービスじゃないから、別に実サービスと一対一対応する必要はない。
例えば、複数のコンテキストにまたがってやりとりされるようなあるコンテキストのメッセージがあるなら、
それは Interchange Context (日本語で言うと相互連結コンテキスト？)のように別のコンテキストとして定義すればいいよね、みたいな話があった。&lt;/p&gt;
&lt;p&gt;せっかく内製開発してて、スクラムやってて、物理的にステークホルダー達とも近い距離にいるのだから、
その恩恵を最大限に活かせるようにしたい。
そのためにDDDって実践的に役立つと思うので、もっと勉強しなければ。&lt;/p&gt;
&lt;p&gt;勉強の一環として今度&lt;a href="https://ddd-alliance.connpass.com/event/25209/" target="_blank" rel="noopener"&gt;DDD Alliance! ドメイン駆動設計のためのオブジェクト指向入門&lt;/a&gt;に行ってみる。
日本でDDDのコミュニティってここくらい？な気がするので、勉強会の内容というよりはコミュニティの様子が気になるので。&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;&lt;a href="https://konklone.com/post/github-pages-now-supports-https-so-use-it" target="_blank" rel="noopener"&gt;GitHub Pages Now (Sorta) Supports HTTPS, So Use It&lt;/a&gt;&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description></item><item><title>忙し過ぎてお弁当も食べられなかった日</title><link>https://www.yewton.net/2016/01/15/diary/</link><pubDate>Fri, 15 Jan 2016 23:00:00 +0900</pubDate><guid>https://www.yewton.net/2016/01/15/diary/</guid><description>&lt;p&gt;最近チームが新体制に移行するという時期で色々バタバタしていて、
立ち上げに伴う開発フローの整備とか、JIRA(プロジェクト管理ツール)の設定とか、
ワーキングアグリーメントの検討とかで、頓に忙しい。&lt;/p&gt;
&lt;p&gt;別に、自分の役割はスクラムマスターではなく、いちメンバーに過ぎないのだけれど、
認定スクラムマスターを取得した身としては色々手を焼かずにはいられず、
色んな雑務を買って出ているという状況。&lt;/p&gt;
&lt;p&gt;それもこれも、スプリント中は〈全力疾走〉するのがスクラムである、
というスクラムのあるべき姿を目指して、自分が全力で開発に打ち込めるようにするため。&lt;/p&gt;
&lt;p&gt;…と思ってたけど、最近は &lt;em&gt;チームのパフォーマンスを引き出す&lt;/em&gt; っていうことに全力になっていて、
それはそれで楽しくなってきたので、スクラムマスターもいいかなー、なんて思い始めた。&lt;/p&gt;
&lt;h2 id="サイト改修"&gt;サイト改修&lt;/h2&gt;
&lt;p&gt;今日もサイトいじりに勤しんだ。&lt;/p&gt;
&lt;p&gt;いじるときはEmacsを使うんだけれど、自分は適当なのでHTML中にJavaScriptを埋め込んだりする。
するとhtml-modeだとシンタックハイライトとかが無くて辛いことになるので、
&lt;a href="http://web-mode.org/" target="_blank" rel="noopener"&gt;web-mode&lt;/a&gt;を使ってる。&lt;/p&gt;
&lt;p&gt;HTMLファイルはCSSファイルは、始めから関連付けておくといいと思う。&lt;/p&gt;
&lt;h3 id="gravatar対応"&gt;gravatar対応&lt;/h3&gt;
&lt;p&gt;静的画像だけでなく、gravatarのアイコンを使えるようにした。&lt;/p&gt;
&lt;p&gt;ついでに、画像を丸く表示するようにした。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/cxfksword/greyshade/blob/28fb061bb674a2add89724dfbbf167f88f381d40/layouts/partials/header.html" target="_blank" rel="noopener"&gt;gravatarに対応している他のテーマ(greyshade)&lt;/a&gt;と、
&lt;a href="https://tdwp.us/round-gravatar-images-wordpress/" target="_blank" rel="noopener"&gt;How to Round Gravatar Images in WordPress&lt;/a&gt;を参考にした。&lt;/p&gt;
&lt;h3 id="記念日対応"&gt;記念日対応&lt;/h3&gt;
&lt;p&gt;最初は&lt;a href="https://counting.hatelabo.jp/" target="_blank" rel="noopener"&gt;Hatena::Counting&lt;/a&gt;とか類似のサービスを利用しようと思ったんだけど、
あんまりシンプルなのが無かったので自作した。&lt;/p&gt;
&lt;p&gt;自作といったって、&lt;a href="https://momentjs.com/" target="_blank" rel="noopener"&gt;Moment.js&lt;/a&gt;というとても便利なライブラリがあったので、
それを使って適当にJavaScriptを埋め込んだだけ。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://golang.org/pkg/text/template/" target="_blank" rel="noopener"&gt;template - The Go Programming Language&lt;/a&gt;とか
&lt;a href="https://gohugo.io/templates/go-templates/" target="_blank" rel="noopener"&gt;Hugo - Go Template Primer&lt;/a&gt;あたりも参考にした。&lt;/p&gt;</description></item><item><title>BettorTouchToolが無料じゃなくなると分かったりした日</title><link>https://www.yewton.net/2016/01/13/diary/</link><pubDate>Wed, 13 Jan 2016 23:00:00 +0900</pubDate><guid>https://www.yewton.net/2016/01/13/diary/</guid><description>&lt;h2 id="bettertouchtool-will-switch-from-free-to-a-pay-what-you-want-model-early-next-year--bettertouchtool-btt-remote-bettersnaptool-and-more"&gt;&lt;a href="https://www.boastr.net/bettertouchtool-may-switch-from-free-to-a-pay-what-you-want-model-early-next-year/" target="_blank" rel="noopener"&gt;BetterTouchTool will switch from free to a “Pay what you want” model early next year. – BetterTouchTool, BTT Remote, BetterSnapTool and more&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.boastr.net/" target="_blank" rel="noopener"&gt;BetterTouchTool&lt;/a&gt;が1月末を目処に無料じゃなくなるらしい。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.boastr.net/btt-paid-faq/" target="_blank" rel="noopener"&gt;FAQ&lt;/a&gt;によると、ライセンスは買い切りで(当面)更新の必要は無く、
過去に寄付してたりといった一定の条件を満たす人は無料でライセンスを取得する手段が提供されるらしい。&lt;/p&gt;
&lt;p&gt;なお、古いのを使い続けるといったことは出来ず、そのうち使えなくなってしまうもよう。&lt;/p&gt;
&lt;p&gt;買うしかないなー。&lt;/p&gt;
&lt;h2 id="割と本気で家庭用slack-botを作ってみた---八発白中"&gt;&lt;a href="https://blog.8arrow.org/entry/2016/01/13/183349" target="_blank" rel="noopener"&gt;割と本気で家庭用Slack Botを作ってみた - 八発白中&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;うちの嫁はSlack使ってくれないから無理ぽ。。
自分もカナヘイスタンプ超気に入ってるから、LINE辞めるのは無理だな。&lt;/p&gt;
&lt;p&gt;記事中で&lt;a href="https://counting.hatelabo.jp/" target="_blank" rel="noopener"&gt;Hatena::Counting&lt;/a&gt;についての言及があった。
ちょうどこういうサービス探してたのでありがたい。
他に世界的にデファクトスタンダードなやつがあるのかとか、調べてみたい。
&lt;a href="https://countingdownto.com/" target="_blank" rel="noopener"&gt;Create a Countdown Clock | CountingDownTo.com&lt;/a&gt;とかが、それらしい感じがする。&lt;/p&gt;
&lt;h2 id="エンジニアにお勧めしたいメモアプリ5選--geechs-magazine"&gt;&lt;a href="https://geechs-magazine.com/tag/lifehack/20160113" target="_blank" rel="noopener"&gt;エンジニアにお勧めしたいメモアプリ5選 | geechs magazine&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;org-modeでだいたい間に合ってるけど、やっぱ同期と多デバイス対応が欲しいよなー。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://mobileorg.github.io/" target="_blank" rel="noopener"&gt;MobileOrg : What is MobileOrg?&lt;/a&gt;はちょっと使ってみて微妙だった。。&lt;/p&gt;
&lt;p&gt;そこだけ何とかなれば。。。&lt;/p&gt;
&lt;h2 id="雑感"&gt;雑感&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;markdown-modeとskkの相性悪いんかな、変換確定しようとすると行頭にカーソルが行ってしまってストレスフルだ。。&lt;/li&gt;
&lt;li&gt;シンタックスハイライトとかEmojiとか使えんのかな。調べよう。&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>はじめに</title><link>https://www.yewton.net/2016/01/11/at-the-start/</link><pubDate>Mon, 11 Jan 2016 11:11:11 +0900</pubDate><guid>https://www.yewton.net/2016/01/11/at-the-start/</guid><description>&lt;h2 id="はじめに"&gt;はじめに&lt;/h2&gt;
&lt;p&gt;今年30歳になる節目の年なので、ブログを書いてみることにした。&lt;/p&gt;
&lt;p&gt;何もこういう試みは初めてではなく、
これまでも、&lt;a href="https://d.hatena.ne.jp/yuto_sasaki/" target="_blank" rel="noopener"&gt;はてなダイアリー&lt;/a&gt;だったり、
&lt;a href="https://qiita.com/yewton" target="_blank" rel="noopener"&gt;Qiita&lt;/a&gt;だったりに断続的に記事を書いたりメモしたりしていた。&lt;/p&gt;
&lt;p&gt;それより以前も、個人でサイト作成したり、既存のブログサービスを使っていたこともあった。&lt;/p&gt;
&lt;p&gt;いずれも、1年と経たずに辞めてしまった。
自分の凝り性でかつ飽きっぽい性質のためだと思う。&lt;/p&gt;
&lt;p&gt;今回また性懲りもなく始めたのは、何かをアウトプットしたいというよりも、
&lt;a href="https://gohugo.io/" target="_blank" rel="noopener"&gt;Hugo&lt;/a&gt;というものを何かのキッカケで知って、
Golangの静的サイト生成ツールだと知り、イマドキは静的サイト生成だよねー
という巷の声を聞いた結果、使ってみたくなった、というのが大きい。&lt;/p&gt;
&lt;p&gt;飽きたらその内また辞めるだろうけれど、
今のところ調整したりカスタマイズしたりしたい部分が多々あるので、当面存在はするだろう。
これらの試みを記事にしたりするかもしれない。&lt;/p&gt;
&lt;h2 id="何を書くか"&gt;何を書くか&lt;/h2&gt;
&lt;p&gt;外部サービスに依存しないので(ホスティングはGitHub使ってるケド)自由奔放に書いていけたらと思っている。&lt;/p&gt;
&lt;p&gt;技術的な話から、日常の駄文、過去の思い出を振り返ってみたり、
あとはペットの話も書くかもしれない。時にはポエムも書くだろう。&lt;/p&gt;
&lt;p&gt;当分人の目に触れぬはずの所なので、好き勝手にやってみよう。&lt;/p&gt;</description></item></channel></rss>