<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="https://www.readonly.xyz/">
  <id>https://www.readonly.xyz/</id>
  <title>R/O</title>
  <updated>2022-07-31T08:39:38Z</updated>
  <link rel="alternate" href="https://www.readonly.xyz/" type="text/html"/>
  <link rel="self" href="https://www.readonly.xyz/blog/feed.xml" type="application/atom+xml"/>
  <author>
    <name>ryot4</name>
    <uri>https://github.com/ryot4</uri>
  </author>
  <entry>
    <id>tag:www.readonly.xyz,2022-07-31:/blog/git-ls/</id>
    <title type="html">CLI で GitHub のようにファイルを一覧表示する</title>
    <published>2022-07-31T08:39:38Z</published>
    <updated>2022-07-31T08:39:38Z</updated>
    <link rel="alternate" href="https://www.readonly.xyz/blog/git-ls/" type="text/html"/>
    <content type="html">&lt;p&gt;CLI でも GitHub 等のようにファイルごとの最終更新を一覧表示したくなることがあるので、簡単なスクリプトを書いた。
&lt;code&gt;git-ls&lt;/code&gt; としてパスの通った場所に置いて &lt;code&gt;git ls&lt;/code&gt; で使えるようにしている。&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/sh

ls_file() {
    file_path="${1%%/}"
    file_basename=$(basename "${file_path}")
    ls_tree_opt=
    if [ -d "${file_path}" ]; then
        file_basename="${file_basename}/"
        ls_tree_opt='-d'
    fi
    file_mode=$(git ls-tree ${ls_tree_opt} HEAD -- "${file_path}" | cut -d ' ' -f 1)
    if [ -n "${file_mode}" ]; then
        git log -1 --pretty=format:"${file_mode} ${file_basename} %x09 %h %s %x09 %cr%n" HEAD -- "${file_path}"
    else
        printf '%s %s \t %s \t uncommitted\n' '------' "${file_basename}" '-------'
    fi
}

path="${1:-.}"
if [ -f "${path}" ]; then
    pattern="${path}"
elif [ -d "${path}" ]; then
    pattern="${path}/.* ${path}/*"
else
    echo "no such file or directory: ${path}"
    exit 1
fi

for file in ${pattern}; do
    case "${file}" in
    "${path}"/.|"${path}"/..)
        continue
        ;;
    "${path}"/.git)
        continue
        ;;
    "${path}/.*"|"${file}/*")
        continue
        ;;
    esac
    ls_file "${file##./}"
done | column -t -s '	'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Gist にも置いてある: &lt;a href="https://gist.github.com/ryot4/245a4b2c28b064c68c1d957b8d580d18"&gt;https://gist.github.com/ryot4/245a4b2c28b064c68c1d957b8d580d18&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;サンプルとして &lt;a href="https://github.com/githubtraining/hellogitworld"&gt;https://github.com/githubtraining/hellogitworld&lt;/a&gt; で使ってみると以下のような表示になる。&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;hellogitworld $ git ls
100644 .gitattributes    bf7a9a5 .gitattributes to make this play nicely onWindows          10 years ago
100644 .gitignore        d2280d0 Adding maven build script                                  10 years ago
100644 .travis.yml       9805760 Fix YAML name-value pair missing space                     8 years ago
100644 README.txt        a13dba1 Even I can change the readme file                          9 years ago
100644 build.gradle      c594793 Added gradle build file                                    10 years ago
100644 fix.txt           78f4771 Fixes #1                                                   10 years ago
100644 pom.xml           ef7bebf Fix groupId after package refactor                         8 years ago
040000 resources/        755fd57 Addition of the README and basic Groovy source samples.    11 years ago
100755 runme.sh          f5ed019 Added shell script to drive the execution of the app       11 years ago
040000 src/              ebbbf77 Update package name, directory                             8 years ago
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;ファイルの数だけ &lt;code&gt;git log&lt;/code&gt; を叩く実装なのでリポジトリによっては結構重い点は要注意。&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:www.readonly.xyz,2021-03-25:/blog/bash-function-for-pushd-and-popd/</id>
    <title type="html">pushd と popd が少しだけ楽になるかもしれない Bash function</title>
    <published>2021-03-25T16:27:38Z</published>
    <updated>2021-03-25T16:27:38Z</updated>
    <link rel="alternate" href="https://www.readonly.xyz/blog/bash-function-for-pushd-and-popd/" type="text/html"/>
    <content type="html">&lt;p&gt;bashrc で引数を与えるとそこに &lt;code&gt;pushd&lt;/code&gt; し、与えないと &lt;code&gt;popd&lt;/code&gt; するだけの関数を定義して使っている。&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pd()
{
    if [[ -n ${1} ]]; then
        pushd "${1}"
    else
        popd
    fi
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;これだけ。push と pop を同じコマンドで行えるところが慣れると便利で割と気に入っている。&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:www.readonly.xyz,2021-02-28:/blog/go-embed-for-cli-tools/</id>
    <title type="html">go:embed で CLI ツールのシェル補完スクリプトをバイナリに埋め込む</title>
    <published>2021-02-28T16:48:56Z</published>
    <updated>2021-02-28T16:48:56Z</updated>
    <link rel="alternate" href="https://www.readonly.xyz/blog/go-embed-for-cli-tools/" type="text/html"/>
    <content type="html">&lt;p&gt;&lt;a href="https://golang.org/doc/go1.16#embed"&gt;Go 1.16 で入った &lt;code&gt;go:embed&lt;/code&gt;&lt;/a&gt; を使って、自作の CLI ツール &lt;a href="https://github.com/ryot4/sidenote"&gt;sidenote&lt;/a&gt;&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; のシェル補完用スクリプトをバイナリに埋め込んでみた。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="https://github.com/ryot4/sidenote/commit/c2ddebefcced2b29d48dc9f4e194f9adde50e533"&gt;Embed shell completion script in the binary · ryot4/sidenote@c2ddebe&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;テキストファイルの内容を文字列として埋め込むだけなら非常に簡単で、以下のようにするだけ。&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href="https://golang.org/pkg/embed/"&gt;&lt;code&gt;embed&lt;/code&gt;&lt;/a&gt; パッケージを &lt;code&gt;import&lt;/code&gt; する&lt;/p&gt;

    &lt;pre&gt;&lt;code&gt;import _ "embed"
&lt;/code&gt;&lt;/pre&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code&gt;string&lt;/code&gt; 変数の宣言の前に &lt;code&gt;//go:embed &amp;lt;ファイル&amp;gt;&lt;/code&gt; で埋め込みたいファイルを指定する&lt;/p&gt;

    &lt;pre&gt;&lt;code&gt;//go:embed path/to/file.txt
var embeddedFileContent string
&lt;/code&gt;&lt;/pre&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;sidenote では埋め込んだスクリプトを出力するだけの &lt;code&gt;completion&lt;/code&gt; サブコマンドを追加&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote" rel="footnote" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;して、Bash であれば &lt;code&gt;~/.bashrc&lt;/code&gt; に&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;source &amp;lt;(sidenote completion bash)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;と書いておけばシェル補完を有効化できるようにした。&lt;/p&gt;

&lt;p&gt;Go で CLI ツールを作る利点の一つにツールがシングルバイナリで動作することがあるが、シェル補完用スクリプトのようにツール本体とは別の付属物がある場合、バイナリに埋め込んでしまうことでユーザに別途インストールしてもらう手間を省くことができる。&lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote" rel="footnote" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;
特に (アーカイブ形式での配布ではなく) &lt;code&gt;go install&lt;/code&gt; でインストールすることを想定しているようなものの場合はうれしいと思う。&lt;/p&gt;

&lt;p&gt;バイナリにファイルを埋め込むためのパッケージは以前から色々と存在していたものの、sidenote はなるべく依存関係を小さく保っておきたい意図で Go の標準ライブラリ以外は使わないようにしていて、自前でファイル埋め込みを実現するのも大変そうなので対応していなかった。
そういう意味で標準のツールチェインでサポートされるようになったことはありがたい。&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
  &lt;ol&gt;
    &lt;li id="fn:1"&gt;
      &lt;p&gt;sidenote については&lt;a href="/blog/cli-note-taking/"&gt;以前の記事&lt;/a&gt;を参照 &lt;a href="#fnref:1" class="reversefootnote" role="doc-backlink"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id="fn:2"&gt;
      &lt;p&gt;サブコマンド名は &lt;a href="https://github.com/kubernetes/kubectl"&gt;kubectl&lt;/a&gt; にならった &lt;a href="#fnref:2" class="reversefootnote" role="doc-backlink"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id="fn:3"&gt;
      &lt;p&gt;これは付属物だけをアップデートしたい場合でもバイナリ全体を更新する必要がある、ということでもあるので、何でもかんでも埋め込めば良いということではない &lt;a href="#fnref:3" class="reversefootnote" role="doc-backlink"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</content>
  </entry>
  <entry>
    <id>tag:www.readonly.xyz,2021-01-16:/blog/cli-note-taking/</id>
    <title type="html">CLI での作業メモをディレクトリ単位で管理する</title>
    <published>2021-01-16T14:41:12Z</published>
    <updated>2021-01-16T14:41:12Z</updated>
    <link rel="alternate" href="https://www.readonly.xyz/blog/cli-note-taking/" type="text/html"/>
    <content type="html">&lt;h2&gt;作業メモの管理どうする問題&lt;/h2&gt;

&lt;p&gt;コンピュータ上で何かしら作業をしながらメモを取る場合、人によって色々な流儀があると思う。私はターミナル上でテキストエディタ (Vim) を起動してプレーンテキストで書くことが多い。&lt;/p&gt;

&lt;p&gt;そうしているとテキストファイルの管理に困りがちで、&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;何も考えずに作業ディレクトリに転がしておく&lt;/strong&gt; → ディレクトリが散らかる。特にバージョン管理されているディレクトリでは、個人的なメモを誤ってリポジトリに入れないように気を付けるのが面倒&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;メモ置き場を一つ決めてそこに全部放り込む&lt;/strong&gt; → 作業とメモが紐づかない。しばらく作業から離れるとメモを探すのに手間取ったり、メモの存在自体を忘れたりする&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;というようなことがあり、折衷案として作業ディレクトリごとにメモ置き場を用意する方法を考えた。
案というほど大したものではなくて、単に専用のディレクトリ (&lt;code&gt;.notes&lt;/code&gt;) を作って全部そこに入れるだけ。&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ mkdir .notes
$ vim .notes/TODO
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;こうしておくと作業ディレクトリの直下がメモで散らかることはないし、バージョン管理システムに無視させる場合もディレクトリ一つの方が扱いやすい。Git の場合は &lt;code&gt;~/.config/git/ignore&lt;/code&gt; にグローバルな ignore 設定を書ける&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; ので、そこに &lt;code&gt;.notes&lt;/code&gt; を追加するだけで済む。&lt;/p&gt;

&lt;p&gt;作業ディレクトリからたどって参照したいけれど、ファイルの実体は作業ディレクトリの外に置いておきたい、という場合もある。例えば定期的にメモのバックアップを取ることを考えると、作業ディレクトリごとに散らばっているよりは一か所にまとまっているほうが扱いやすい。これはシンボリックリンクを使えば簡単に実現できる。&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ mkdir -p ~/notes/some-project
$ ln -s ~/notes/some-project/ .notes
$ vim .notes/TODO
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;これですべて解決……とはならなくて、&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;毎回 &lt;code&gt;vim .notes/TODO&lt;/code&gt; のようにパスを指定するのは面倒&lt;/li&gt;
  &lt;li&gt;サブディレクトリからメモを開こうとすると &lt;code&gt;vim ../../.notes/TODO&lt;/code&gt; みたいなのが発生しがちで、やはり面倒&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;という問題がある。このあたりの手間を減らすものがあるとうれしい……ということで、&lt;a href="https://github.com/ryot4/sidenote"&gt;sidenote&lt;/a&gt; という小さい CLI ツールを作って使っている。&lt;/p&gt;

&lt;h2&gt;sidenote のかんたんな紹介&lt;/h2&gt;

&lt;p&gt;インストール方法は &lt;a href="https://github.com/ryot4/sidenote#installation"&gt;README&lt;/a&gt; を参照。
シングルバイナリで動くコマンドで、Bash 用のコマンドライン補完もある。&lt;/p&gt;

&lt;p&gt;機能はサブコマンドに分かれていて、v0.1.6 時点では以下の通り。&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ sidenote -h
Usage: sidenote [-d path] [-version] &amp;lt;command&amp;gt; [command-arguments]

options:
  -d string
        Specify the directory for notes (env: SIDENOTE_DIR)
  -version
        Print the version and exit

commands:
  cat       Print contents of notes
  edit      Open notes with the editor ($VISUAL or $EDITOR)
  import    Import a note from the existing file or the standard input
  init      Initialize the directory for notes
  ls        List notes
  path      Print the path of notes
  rm        Remove notes
  serve     Serve notes over HTTP
  show      Open notes with $PAGER

Run sidenote &amp;lt;command&amp;gt; -h for usage of each command.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;何かを書きたくなったら、まず &lt;code&gt;init&lt;/code&gt; コマンドでカレントディレクトリ直下にディレクトリ (デフォルトでは &lt;code&gt;.notes&lt;/code&gt;、名前は変更可能) を作る。&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ sidenote init
initialized .notes
$ ls -dl .notes
drwxr-xr-x 2 ryot4 ryot4 4096 Feb  9 19:03 .notes
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;カレントディレクトリの外にファイルを置きたい場合は &lt;code&gt;init -l&lt;/code&gt; にパスを与えてその場所へのシンボリックリンクを作る。
指定したパスにディレクトリが存在しない場合は自動的に作成される。&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ sidenote init -l ~/Documents/notes
initialized .notes (-&amp;gt; /home/ryot4/Documents/notes)
$ ls -l .notes
lrwxrwxrwx 1 ryot4 ryot4 31 Feb  9 19:03 .notes -&amp;gt; /home/ryot4/Documents/notes
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;準備は以上で、メモの作成・編集は &lt;code&gt;edit&lt;/code&gt; コマンドで行う。例えば、&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ sidenote edit TODO
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;とすると &lt;code&gt;.notes/TODO&lt;/code&gt; をデフォルトのエディタ (&lt;code&gt;$VISUAL&lt;/code&gt; または &lt;code&gt;$EDITOR&lt;/code&gt; に設定されているもの) で開く。
&lt;code&gt;.notes/&lt;/code&gt; の部分は裏側で自動的に補われるので手で指定する必要はない。&lt;/p&gt;

&lt;p&gt;カレントディレクトリに &lt;code&gt;.notes&lt;/code&gt; が存在しない場合、&lt;code&gt;sidenote&lt;/code&gt; はディレクトリ階層を上にたどって探す。&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote" rel="footnote" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt; 例えば&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ tree -aF project
project/
├── .notes/
│   └── TODO
└── src/
    └── module/

    3 directories, 1 file
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;のようなディレクトリ構造がある場合、&lt;code&gt;module&lt;/code&gt; ディレクトリの中で &lt;code&gt;sidenote edit TODO&lt;/code&gt; を実行すると&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code&gt;module&lt;/code&gt; の直下には &lt;code&gt;.notes&lt;/code&gt; が無いので一階層上の &lt;code&gt;src&lt;/code&gt; を見る&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;src&lt;/code&gt; の直下にも &lt;code&gt;.notes&lt;/code&gt; が無いので一階層上の &lt;code&gt;project&lt;/code&gt; を見る&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;project&lt;/code&gt; の直下に &lt;code&gt;.notes&lt;/code&gt; があるので、その中の &lt;code&gt;TODO&lt;/code&gt; をエディタで開く&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;という動きになる。この挙動によってサブディレクトリの中でも相対パスを意識せずにファイルを扱える。&lt;/p&gt;

&lt;p&gt;基本はこれだけで、他にファイルの一覧 (&lt;code&gt;ls&lt;/code&gt;) や内容の表示 (&lt;code&gt;cat&lt;/code&gt; / &lt;code&gt;show&lt;/code&gt;)、削除 (&lt;code&gt;rm&lt;/code&gt;) などを行うコマンドがある (より詳しい使い方は &lt;a href="https://github.com/ryot4/sidenote#quick-start"&gt;README&lt;/a&gt; を参照)。&lt;/p&gt;

&lt;h2&gt;既存のコマンドを使って楽をする&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;sidenote&lt;/code&gt; コマンドはなるべく単純なものにしたいと思っていて、例えば検索を行うサブコマンドは存在しない。
代わりに &lt;code&gt;.notes&lt;/code&gt; ディレクトリの場所を出力する &lt;code&gt;path&lt;/code&gt; コマンドがあって、これと既存の検索コマンドの組み合わせで検索を行えるようになっている。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;path&lt;/code&gt; コマンドは今いるディレクトリに対応する &lt;code&gt;.notes&lt;/code&gt; ディレクトリのパスを出力するもので、上の &lt;code&gt;module&lt;/code&gt; ディレクトリの例だと以下のようになる。&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module$ sidenote path
../../.notes
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;これを使うと、例えば全てのメモの中から &lt;code&gt;XXX&lt;/code&gt; という文字列を &lt;code&gt;grep&lt;/code&gt; したい場合は以下のようにできる。&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ grep -R XXX "$(sidenote path)"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;例えば &lt;code&gt;sidenote grep XXX&lt;/code&gt; のような組み込みの検索コマンドを用意する方が直感的でコマンド入力も楽になるけれど、&lt;code&gt;path&lt;/code&gt; と外部コマンドを組み合わせる方法は検索に &lt;code&gt;grep&lt;/code&gt; 以外のものを使いたくなった場合でも対応できるし、検索に限らず「ファイルパスを受け取って何かする」類の処理全般に応用できるので柔軟性がある。
何より、実装量を減らせるので楽で良い。&lt;/p&gt;

&lt;p&gt;同様に、&lt;code&gt;cd "$(sidenote path)"&lt;/code&gt; でメモの在りかに移動すれば通常のファイル操作を行えるので、&lt;code&gt;cp&lt;/code&gt; や &lt;code&gt;mv&lt;/code&gt; のような複雑なファイル操作 &lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote" rel="footnote" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt; もサブコマンドとしては用意していない。&lt;/p&gt;

&lt;h2&gt;実装&lt;/h2&gt;

&lt;p&gt;sidenote は Go で書いた。この手のツールは簡単に使い始められることが重要だと思うので、シングルバイナリで動作する点は大きい。
また、依存関係のメンテナンスを考えずに済むように Go の標準ライブラリだけを使用して書いている。
大したことはしていないので実際のところシェルスクリプトで書いても良かったかもしれないけれど、それはそれで実装が辛いことになっていたかもしれない。&lt;/p&gt;

&lt;p&gt;あと、Bash のコマンドライン補完をまともに実装したのはこれが初めてだった。
通常と異なるファイルパスの解釈をするツールなのでファイルパスの補完を行う &lt;code&gt;_filedir&lt;/code&gt; がそのまま使えなかったりしてやや苦労したものの、やはり補完の有り無しでコマンドの使い勝手に天と地の差があるので用意してよかったと思う。&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
  &lt;ol&gt;
    &lt;li id="fn:1"&gt;
      &lt;p&gt;正確には &lt;code&gt;$XDG_CONFIG_HOME/git/ignore&lt;/code&gt; &lt;a href="#fnref:1" class="reversefootnote" role="doc-backlink"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id="fn:2"&gt;
      &lt;p&gt;これは &lt;code&gt;git&lt;/code&gt; コマンドが &lt;code&gt;.git&lt;/code&gt; を探す際の挙動とだいたい同じ &lt;a href="#fnref:2" class="reversefootnote" role="doc-backlink"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id="fn:3"&gt;
      &lt;p&gt;単純そうに見えるが、ちゃんと実装しようとすると考えるべきことが多くて大変 &lt;a href="#fnref:3" class="reversefootnote" role="doc-backlink"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</content>
  </entry>
  <entry>
    <id>tag:www.readonly.xyz,2020-06-26:/blog/making-terminal-colorscheme/</id>
    <title type="html">ターミナルのカラースキームを自作した</title>
    <published>2020-06-26T14:12:38Z</published>
    <updated>2020-06-26T14:12:38Z</updated>
    <link rel="alternate" href="https://www.readonly.xyz/blog/making-terminal-colorscheme/" type="text/html"/>
    <content type="html">&lt;p&gt;長時間ターミナルを眺めて作業していると目の疲れを感じることが増えてきたので、目に優しい配色を目指してターミナルのカラースキームを自作してみた&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;

&lt;p&gt;以下で公開している。(2021-04-11 追記: 名前を変えて GitHub に移した)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ryot4/Hikage"&gt;ryot4/Hikage&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;全体的に彩度を抑えているのが特徴。数日間使ってみて目が痛くなったりはしていないので、それなりに目論見通りにはできた気がする。(使いながら何度か調整はした)&lt;/p&gt;

&lt;h2&gt;使ったもの&lt;/h2&gt;

&lt;p&gt;これからカラースキームを作りたい人の参考になるかもしれないので紹介。&lt;/p&gt;

&lt;dl&gt;
  &lt;dt&gt;&lt;a href="https://terminal.sexy/"&gt;terminal.sexy&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;Web ブラウザ上でターミナルのカラースキームを作成できるツール&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote" rel="footnote" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;。iTerm2 や Xresources などの設定をインポートして別のフォーマットでエクスポートできるので、自分ではカラースキームを作らない場合にも役立つかもしれない。&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="https://webaim.org/resources/contrastchecker/"&gt;Contrast Checker&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;2つの色 (前景色と背景色) のコントラスト比を確認できるツール。色の組み合わせが &lt;a href="https://waic.jp/docs/WCAG20/Overview.html#visual-audio-contrast"&gt;WCAG 2.0&lt;/a&gt; に適合しているかどうか教えてくれるので、見やすさに問題がないか客観的に確認できる。&lt;/dd&gt;
  &lt;dt&gt;Windows Terminal&lt;/dt&gt;
  &lt;dd&gt;設定がテキストファイルで、保存すると即座に画面に反映される点は試行錯誤するのに便利だった。&lt;/dd&gt;
&lt;/dl&gt;

&lt;p&gt;見栄えの確認は実際に色付きの出力をするコマンド (ls とか vim とか tmux とか) で試すほかに、簡単なスクリプトで色の組み合わせを一覧表示&lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote" rel="footnote" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;して眺めたりもした。&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-sh"&gt;#!/bin/sh

echo
for bg in '' $(seq 40 47); do
    for bold in '' 1; do
        for fg in '' $(seq 30 37); do
            code="${bold}${fg:+;$fg}${bg:+;$bg}"
            code="${code#;}"
            printf '\033[%sm%7sm \033[0m' "${code}" "${code}"
        done
        echo
    done
done
echo
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;出力はこんな感じになる。&lt;/p&gt;

&lt;p&gt;&lt;img src="colortable.png" alt="colortable" width="450px" /&gt;&lt;/p&gt;

&lt;div class="footnotes" role="doc-endnotes"&gt;
  &lt;ol&gt;
    &lt;li id="fn:1"&gt;
      &lt;p&gt;ここ数年は &lt;a href="https://en.wikipedia.org/wiki/Tango_Desktop_Project#Palette"&gt;Tango Desktop Project のカラーパレット&lt;/a&gt; (を少しいじったもの) を使っていた。最近だと Windows Terminal の&lt;a href="https://docs.microsoft.com/ja-jp/windows/terminal/customize-settings/color-schemes"&gt;デフォルト設定&lt;/a&gt;にも Tango のカラースキームが付属している。 &lt;a href="#fnref:1" class="reversefootnote" role="doc-backlink"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id="fn:2"&gt;
      &lt;p&gt;他に Web 上でターミナルのカラースキームを作成できるツールとしては &lt;a href="https://ciembor.github.io/4bit/"&gt;4bit Terminal Color Scheme Designer&lt;/a&gt; がある。こちらは個々の色を細かくいじることはできないが、その分手軽で統一感のあるカラースキームを作りやすい。 &lt;a href="#fnref:2" class="reversefootnote" role="doc-backlink"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id="fn:3"&gt;
      &lt;p&gt;ターミナル上での色付き出力は &lt;a href="https://en.wikipedia.org/wiki/ANSI_escape_code"&gt;ANSI エスケープコード&lt;/a&gt; を使って行う。この手のスクリプトは Web 上で探すといろいろ見つかるが、&lt;a href="http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html"&gt;Bash Prompt HOWTO 6.1. Colours&lt;/a&gt; の最後に載っているものがカラースキームの紹介ではよく使われている (と思う)。 &lt;a href="#fnref:3" class="reversefootnote" role="doc-backlink"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</content>
  </entry>
</feed>

