タグ "開発" が付けられた記事

ちゃんとしたGitコミットメッセージをCommitzenを日本語で使って楽に書く

  1. 1. 決定打は’Commitzen’
  2. 2. タイプ、スコープの効能
  3. 3. 日本語でどうしましょ?
  4. 4. Commitzenを少しだけ日本人に優しくしました
    1. 4.1. 使い方
  5. 5. もうちょっと拡張するには
    1. 5.1. 使い方

Gitを使うようになって以来、使えば使うほどこれは良いバージョン管理だなぁと関心する。その反面、コミットに対しての悩みはつきない。コミットメッセージ、粒度。そのへんをどうしたら良いのか決定打が無いまま、ちゃんとしてるっぽいようにできてはいるけど今イチ自信がないままだった。

そう思いつつもいろいろと思考錯誤してようやく最近ではこれで行こう! と自信もって上手くできてる感がでてきたのでそのへんのことを共有していこう。

決定打は’Commitzen’

Commitzenは一言で言えば対話的にコミットメッセージを作るやつ。NPMで配布されていて、Angularで使われているコミットメッセージのルールが元になってるそうな。

簡単に言えば

Type(Scope): Title

Body

というメッセージルールで書く。ScopeBodyに関してはオプショナルでなくても可。
タイプは例えば、feat, fix, style とか。大項目みたいな。
スコープは言わずもがな。変更範囲。タイトルは普通のコミットメッセージみたいなコミットの要約で、Bodyはさらに細かい説明、これはよくある1行空けて詳細を説明、みたいなのと一緒。
これを対話的に

  1. このコミットのタイプは? (選択式)
  2. スコープは?(enterでスキップ)
  3. コミットの要約
  4. さらに細かい説明(オプショナル)
  5. 破壊的変更について
  6. 関連するissueについて

みたいな感じで質問に答えるように入力する。こうすることによって「うーん、コミットメッセージ、どう書こう」みたいなのをちょっと楽にしてくれる。さらには、タイプを選択式にすることによってメッセージの統一性を強制し、スコープをちゃんと考える契機にもなる。

タイプ、スコープの効能

実はメッセージを入力するのが楽になるだけじゃなくて「メッセージと内容の整合性」をちゃんと意識してる場合、変更内容の粒度や区切りもある程度しっかりしてくる。

バグ修正のコミットに機能追加を含めてはいけない。後からアレコレしたい場合に無理が生じてくる。Gitの良いところは履歴であり戻れることなので、戻りやすく、選択できるレベルにしておくのが良い。だけど例えばバグ修正と機能追加が1つのコミットにある場合、バグ修正は取り込みたいけど、機能追加は問題があって取りこみたくない、という場合に死ぬ。

さらにconventional-changelogというのがcommitzenプロジェクトの一環にある。これはこのタイプを自動で判別してCHANGELOG.mdを自動生成したり、セマンティックバージョニングをコントロールする方法。簡単に言えばfixが含まれていれば0.0.1(patch)上がってfeatが含まれていれば0.1.0(minor)上がる。

日本語でどうしましょ?

僕は個人的に言えばプライベートなものかつ、日本人のみのチームで作業されるものは日本語コミットメッセージで良いと思ってる。コミットメッセージを書くためにうんうん悩んで時間を浪費したりするのは本質じゃないし、読むときもいちいち機械翻訳にかけて理解するのももったいない。

ただし、被検索性は高くもっていたいのでそれなりなルールは必要で、コミットメッセージに日本語か嫌われるのはこのへんが大きいとにらんでる。問題は文法と表記のあいまいさ。

英語だとSVC文法で、さらに本質から先に出てくる。日本語は逆でSCVというか、大切なことほど後にでてくる(ごめんなさい、このへんの言語的な細かいことは正確に解説できる知識がないです)

fix SomeClass work properly

というメッセージと

SomeClassが正しく動作するように修正

というメッセージ、どっちが見やすい? 英語のほうが理解しやすいように思う。後からコミットメッセージをもとに探す場合、もう何でさがしたらいいかわからない。バグフィクスって書く? 修正って書く? っていう表記揺れだったり、「修正」が最後に来るので目で追う場合もズレる。文字数が多くなって自動でBodyに送られた場合はさらにキツい。

で、じゃあ表記揺れをルールで縛ってある程度書き方も一文じゃなくて配慮したルールにしてみたとしよう(これは以前僕が日本語コミットを書くなら、と独自に考えてみたもの)

修正: SomeClassが正しく動作するように

もしくは「修正」を外に出したので説明を追加すると

修正: SomeClassが正しく動作するようにsome-functionを追加

とか。これならまず本質が「修正」であることがわかるし、メッセージの最初が主語なのでSomeClassに対する修正だな、とわかりやすいと思う。そしてこれをAngularルールで書いてさらに日本語を混ぜると

fix(SomeClass): add some-function for working properly

fix(SomeClass): 正しく動作するようにsome-functionを追加

日本語話者にとってもタイプとスコープ程度は英語でも誰も困らないし、ちゃんと明記されてるし、その後の説明は日本語でも何をしたのかわかるし。まずタイプとスコープを最初に固定することでそのあとメッセージがもうちょっと変更内容をちゃんと説明しやすく書ける。

これだと日本語コミットでもわかりやすいし、バランスも良いと思う。もちろんパブリックなリポジトリや日本語話者のみで構成されていなければ英語で書くべきなのは言うまでもないけど。

Commitzenを少しだけ日本人に優しくしました

そんなわけで、日本語で書こうが英語で書こうがCommitzenが役に立つのはわかってもらえたはず。で、日本語で書くような場合、対話型で設定できたとしてもまだちょっとやりづらい。英語にそこまで不自由を感じないようになった僕でも日本語を読むほうが圧倒的に速い(漢字は文字あたりの情報量が圧縮されているということ抜きにしても)。

で、commitzen(cz-cli)は何もしないと対話的CLIのところにcz-conventional-changelogが使われている。ここを~/.czrcとかで別のものに指定ができるような作りなのでcz-conventional-changelog-jaというもの作った。作ったと言ってもオリジナルをフォークして日本語訳しただけなのですがね。

これを適用すると対話の質問やタイプ選択の説明が日本語になる。自分でも使ってみたけど、英語でコミットするにしてもこっちのほうが使いやすい。

使い方

グローバルに設定してプロジェクト問わず使うとしたら

$ yarn global add cz-cli cz-conventional-changelog-ja
# or npm i -g cz-cli cz-conventional-changelog-ja

とインストールしたら、ユーザー直下に

~/.czrc
{
"path": "cz-conventional-changelog-ja"
}

としてやる。そうすると

$ git cz

とやったときにデフォルトのcz-conventional-changelogではなくcz-conventional-changelog-jaを参照するので、日本語で表示されるようになるはず。

もうちょっと拡張するには

それで使ってたんだけどどうも僕がメッセージ書いててタイプの種類が少なかったり合わなかったり感じてた。コミットメッセージを書きやすくするためのツールなのにこの場合のタイプはうーんどうしよう、みたいに詰まるのは本末転倒だなぁ、と。

もちろんこのTypesを制御する方法ああるんだけど、これってプロジェクトやチームによっても変わるのでもっと柔軟なほうが良さそう。その都度別バージョンのcz-conventional-changelogをフォークしたりするのも違うよなぁって思いもあってcz-customizable経由でやることにした。

cz-customizableは、質問やタイプ情報の設定を外部から読み込めるようにして、カスタムできるようにしたもの。なので日本語で使う場合も.cz-config.jsを書いて参照するようにしたらいい。

参考までに僕の設定を載せておきます。

使い方

運用としては、上の-jaのようにグローバルに設定してプロジェクト問わず使うとしたら

$ yarn global add cz-cli cz-customizable
# or npm i -g cz-cli cz-customizable

とインストールしたら、ユーザー直下に

~/.czrc
{
"path": "cz-customizable"
}

cz-cliが参照するのをcz-customizableにする。で、cz-customizableはデフォルトでは.cz-config.jsを参照するので、下記のようにファイルを作って置く、と。

~/.cz-config.js
'use strict';
module.exports = {
types: [
{
value: 'feat',
name: 'feat: 新機能',
title: 'Features'
},
{
value: 'fix',
name: 'fix: バグ修正',
title: 'Bug Fixes'
},
{
value: 'HOTFIX',
name: 'HOTFIX: 致命的で緊急なバグ修正',
title: 'Critical hotfix'
},
{
value: 'UI',
name: 'UI: UIやスタイルの更新',
title: 'UI'
},
{
value: 'docs',
name: 'docs: ドキュメントのみの変更',
title: 'Documentation'
},
{
value: 'style',
name: 'style: フォーマットの変更\n (コードの動作に影響しないスペース、フォーマット、セミコロンなどの変更)',
title: 'Styles'
},
{
value: 'texts',
name: 'texts: 文字や文章の更新',
title: 'Text and literals'
},
{
value: 'i18n',
name: 'i18n: 国際化',
title: 'Internationalization'
},
{
value: 'typo',
name: 'typo: タイプミスの修正',
title: 'Typos'
},
{
value: 'refactor',
name: 'refactor: リファクタリングのための変更\n (機能追加やバグ修正を含まない変更)',
title: 'Code Refactoring'
},
{
value: 'perf',
name: 'perf: パフォーマンスの改善のための変更',
title: 'Performance Improvements'
},
{
value: 'ux',
name: 'ux: ユーザーエクスペリエンス/ユーザビリティの改善',
title: 'UX'
},
{
value: 'test',
name: 'test: 不足テストの追加や既存テストの修正',
title: 'Tests'
},
{
value: 'config',
name: 'config: 設定の追加や変更',
title: 'Configuration'
},
{
value: 'build',
name: 'build: ビルドシステムや外部依存に関する変更\n (スコープ例: gulp, broccoli, npm)',
title: 'Builds'
},
{
value: 'ci',
name: 'ci: CI用の設定やスクリプトに関する変更\n (スコープ例:Travis, Circle, BrowserStack, SauceLabs)',
title: 'CI'
},
{
value: 'chore',
name: 'chore: その他の変更\n (補助ツール、ドキュメント生成などのソースやテストの変更を含まない変更)',
title: 'Chores'
},
{
value: 'WIP',
name: 'WIP: 作業中',
title: 'WIP'
}
],
scopes: [
// { name: '*' },
// { name: 'admin' },
// { name: 'exampleScope' },
// { name: 'changeMe' }
],
// it needs to match the value for field type. Eg.: 'fix'
/*
scopeOverrides: {
fix: [
{name: 'merge'},
{name: 'style'},
{name: 'e2eTest'},
{name: 'unitTest'}
]
},
*/
// override the messages, defaults are as follows
messages: {
type: 'コミットする変更タイプを選択:\n',
scope: '変更内容のスコープ(例:コンポーネントやファイル名)(optional):\n',
// used if allowCustomScopes is true
customScope: '変更内容のスコープ(例:コンポーネントやファイル名)(optional):\n',
subject: '変更内容を要約した本質的説明:\n',
body: '変更内容の詳細("|"で改行)(optional):\n',
breaking: '破壊的変更についての記述(optional):\n',
footer: '関連issueを追記 (例:"fix #123", "re #123")(optional):\n',
confirmCommit: 'このコミット内容でよろしいですか?'
},
allowCustomScopes: true,
allowBreakingChanges: ['feat', 'fix']
};

もし参考にしていただけたら幸いです。

新しいタブがお好みの背景画像のMarkdownメモになるGoogleChrome拡張を作っている

  1. 1. 概要
  2. 2. 作った理由
  3. 3. ここに来てアップデートと紹介した理由
  4. 4. 技術的な話
  5. 5. 余談

実は最初のバージョンを公開してからけっこうたつんだけど、つい最近いろいろとアップデートしてみたので、ちゃんとお知らせしようと思います。こういうやつ。

YANTAN Preview

概要

  • Cmd+N とかでChromeの新しいタブを開いたときに表示されるページを置きかえるやつ
  • Markdownで書ける。GFMだからタスクリスト記法も対応してる
    • 簡易的な入力補完もつけた
  • どっからか(e.g. Flickr, 500px)の画像を参照するのではなく自分でローカルファイルを選択
    • 美麗な画像 = お気に入りの画像 とは限らないので
  • 画像にフィルタかけたり、文字色の設定とかできる

詳しくは紹介ページを作ったのでそちらを御参照頂きたい。

作った理由

同じような新しいタブページにメモできるようなやついろいろにインスパイアされたのは間違いない。というか既存のものが気に食わないから作るに至った。
というのも有名どころとかって確かにカッコ良くて綺麗な画像をランダムで表示してくれたりするんだけど、概要でも書いたようにそれが自分のお気に入りかというとそうじゃないんだよね。

で、僕には世界を旅行してフラフラしてる間にとった自分にとってかけがえのなく、そして誰にでも胸を張って見せれるような綺麗でお気に入りで思い入れのこもった写真がある。例えば既存の綺麗が画像が表示されるやつでマチュピチュとか表示されるでしょ、そうすると「おー、行ったなぁ」ってなる。なるんだけど写ってるは自分の写真じゃない、そこが納得行かなかった。

もちろん僕だけじゃなくて、風景写真とかじゃなくて例えばアニメやゲームの画像が良いよ、とかって人も居るだろうと思った。そういうのが、自分の好きな背景にしたかった理由。

あとはちょっとササっとメモ取るときに、エディタとは違う場所にメモとりたいときとかあって。Markdownで書けたら簡単になんでもイケるし。

ここに来てアップデートと紹介した理由

アップデートも紹介も前からしたいなーと思いつつ後回しにしてた。つい最近’Markdown New tab’っていうGoogle Chrome拡張が少しバズったりしてたので「おいおい、同じようなの僕もけっこう前に作ったじゃん!」ってなんか憤慨した。

そっから今までやりたいなーと思ってたらローカル画像をキャッシュして使ったり(それまではURLを入れてそこから取得してた)、入力補完を入れたり。ちょいちょいアップデートした。

以前PentazeminというElectronアプリも作ったんだけど、そのときに紹介ページをつけただけでグっと見てもらえる、使ってもらえる率が上がったので、今回も作った。それが上で紹介してるやつ。
このPentazeminもアップデートはそのうちしたい。かなりのポテンシャルあるし。

まあそんなわけでアップデートして紹介ページも整えました。

技術的な話

作ろう! と発起したきっかけのひとつに、あれ、SPAの技術ってChrome拡張でも活きるんじゃね? と思ったことが大きい。
で、実際に使ってのはVue.js。大枠部分は本当楽しく気楽につくれていて幸せ。

ちょっと苦労したのは入力補完。というのもやってる実装は

  1. 特定のキーの時にイベント発火
  2. その中で現在のキャレット位置を特定
  3. キャレットの位置を利用して全文を行ごとにわけて現在の行を特定
  4. 現在の行が補完すべき状況だったら、補完する文字をキャレットの部分に挿入
  5. キャレットの位置を挿入した文字数だけズラす

という流れ。もしかしたらもっと良い実装があるかも。とにかくこのキャレットと入力文字の周りがけっこうやっかい。発火タイミングはKeyupなのかKeydownなのか、対象がReturnキーだったので改行が入ったり入らなかったりして。結局Keydown時にイベントをpreventで奪って、補完しない時は改行を、補完するときは補完文字と改行を挿入するようにしてる。

リリースに関しては、「webpro/release-it: CLI release tool for Git repos and npm packages.」を使ってみてる。なかなか良い。でもまだ最後の方でコケてしまうのが解消できなくて悩んでる。とはいえ、ビルド、自動でパッケージのバージョン表記を更新、タグ付けてPush、あたりまでできてるので実用には耐えれている。
本当はそのあとReleaseに上げて、それをフックにしてChrome拡張配布用のAPI叩いて自動リリース、までやらせたいんだけど…

ちなみに紹介ページはPentazemin時につかったNuxt.jsを改変してシュシュっと作った。といっても一日半かかってしまったけど。まあこれはアイコンや紹介画像、ロゴっぽいやつとか画像制作に時間かかってるのもあるから仕方ない。ただこの画像と説明があるとないとで全然違うので、サボらない。

余談

とまあここまで既に余談だけど、さらに余談。

自分がプライベートで作るものはよっぽど日本特化じゃないかぎり英語ファーストで作ってる。これは、僕が世界をいろいろ見た結果の感覚として、日本は貶すファーストの減点法で評価したがるし、欧米圏はわりと褒めるファーストの加点法で評価したがる傾向だと思ってるから。
趣味でやってるレベルのもので叩かれて無駄に精神力は削られたくないし、褒められるほうが嬉しくてモチベーションアップにつながるから。

わざわざツライ環境で戦うことを選ぶほど僕はマゾじゃない。

あとは寄付を募りたくて悩んでる。基本的に趣味プロダクトはフリーで提供していきたいと思ってるんだけどやっぱりサポートはあったほうがいい。今はPaypal.meだったりKyashだったり個人間送金が昔より手軽になって良い。でも、法的にどうなのか良くわからないので躊躇してる。
ソフトウェア販売(但し払わなくても使える)という形式にするとか、ギフト券とか、ウィッシュリストとかいろいろ方法はあるんだろうけど、それも本当に法的セーフなのはどれなのか、とかよくわからない。

お金により発生するモチベーションと評価は欲しい。

自分が欲しいと思うものを作ってるだけなので当たりまえなんだけど、それなりに使い勝手の良い拡張だと思うので、もし良ければ入れみて試していただけると嬉しい。Chrome拡張なら削除も簡単だし、Vivaldiでも使えてるよ。

モンスターハンターワールド モンスター弱点早見システムを作った

  1. 1. 概要
    1. 1.1. 経緯的な話
    2. 1.2. 開発的な話
    3. 1.3. バズらせるというか知らしめる話

狩人のみなさまにおかれましては楽しいハンターライフを送っておりますか?

タイトル通りなんだけど、MHW向けにせっかくなのでスマホから簡単に見れるシステムを作った話。
作ったものはここ。
MHW 弱点検索

概要

こんな感じ。
サムネイル

  • 検索というよりフィルタ
  • ロード時間とか、準備時間にササッと確認できると良いなあ
  • 種類や名前を指定してそのモンスターの弱点とかを表示するシンプルなシステム
  • キーワードも対応してる、AND、ORも使える
  • なにげに英語対応した
  • PWA対応なのでスマホのホームに登録すると捗る

経緯的な話

以前にGoogle SpreadSheetに作ったやつがあるけど、あれでも十分だったところ、たまたま仕事の技術勉強会での発表の出番が周ってきて何か動くサンプルが欲しかったのでチャチャッとそれらしきものを作ったのがきっかけ。ちなみに発表の内容は、静的なページであってもJavaScriptで何か動いてるとしたらそこにテスト必要だよね、という感じ。

ちなみに勉強会には間に合わず、プロトタイプというかただボタン押すと動くやつ、みたいなので発表した。とはいえそこで原型はできたちゃったので、それをベースにちゃっちゃっと完成させた。勉強会でサンプルで書いたテスト以外は書いてない。本末転倒。

とはいえ実用十分だし、つながりのある人達がフィードバックしてくれるし、自分も使ってみてちょこちょこアップデートを繰り返してようやく一段落。

開発的な話

静的ページオンリーで行こうと思ったので、いっそのこと純SPA的に作ろうと思った。そして利用者のスタイルとしてゲームやりながらスマホをいじるのがメインと思われたことからPWAにしてみる。

スマホ特化なのでいろいろフレームワークを検討したけど、OnsenUIがてっとり早そうだったのと僕の好きなVue.js用があったので採用。使ってみての感想はいろいろとちゃちゃっと作るには良くできてるけど、混みいったことをやろうとすると癖とかが足枷になりえたり。まぁそれはどのフレームワーク使ってもそうなんだろうけど。

Vue.jsは以前作ったPentazemin以来しばらく間が開いたので、再入門的な感じになった。ただPentazeminの時にいろいろ頑張ったせいか、だいぶサクサク作れた。あそこで独力で頑張った努力は無駄どころか自分にとって大きな資産になってる感をすごく感じた。それとともに今回もちょっと違ったことやったりで知見が増えた感覚もある。

特にSPAにしつつもURLで言語環境分けたり、ローカライズ周りだったり。あとはキーワードの実装もなかなか頭をひねった。そう思うとこういう自分の好きな題材で好きなフレームワークや開発技術を持ちいて趣味開発するの最高に良い。ちょうどゲームのほうも落ちついてきたので気持ち的にも良かった。

最初はGitHub-Pagesで運用しようと思ったけどなんかファイルが上手く読まれないのでNetlifyで。このブログでも使っるNetlifyだけど改めて便利さを思い知った。静的なものであればNetlifyに上げさえすれば動くので、内部的に動的な要素を必要としないなら十分だし手軽で最高。SPAがっつり作れば動的っぽいけどフロントエンドでどうにでもできちゃうのでこれで事足りちゃうってのがまたすごい。便利な世の中で幸せ。

バズらせるというか知らしめる話

せっかく作ったのでいろんな人に使って欲しいのは当然だと思う。そうしていろいろと知らせてみたものの、バズらせるのって難しい。

Twitterでお知らせするも僕のフォロワーはそんな多くない。ハッシュタグつけたら良いんかと思ったけどこれが実は簡単な話じゃなかった。というのも、Twitter公式で見てるとハッシュタグつけても拾われるのは何らかのアルゴリズムが噛んでる。人気があるのが良く表示されるというか、表示される為の人気を取るハードルが高すぎる。特に同じタグでかなりの数のツイートされてる場合。
公式で見てない場合、時系列的に載るとは思うんだけどここも流れが早すぎて流れてしまう。画像がないからかな、と思ってプレビュー画像を作ってみたけど変わらず。これは時間帯とかも関係すると思うのでなかなか一概に言えず。

5chやまとめサイトで情報が載るのが一番良さそうだけど、5chってそういう宣伝的なのを嫌う傾向にありそうだし、まとめサイトってなにをどう拾ってるのかよくわからん。5chに載るのは、宣伝じゃなく上手く貼るような独特の手法が必要そうな気がする。5ch専用ステマというか。よくポジティブに話題になるのは、なんか上手いこと工作してるんだろうなあ、と思う。

一方で英語対応したので海外掲示板のRedditにも載せてみた。こっちは5chみたいな暗黙の了解みたいなのとかないので自分でバシっと。スレ立てて1時間も立たないうちに感謝のコメント付いたのでだいぶ嬉しかった。本当、日本には存在しない感謝や褒めるのを惜しまない文化は素敵。というか日本で感謝と褒めを惜しむ文化ってなんなんだろう。みんな褒めたり感謝しあったりするほうがハッピーに暮らせると思うよ。誇張じゃなくて、その文化の違いだけで移住する価値十分にあるケースも少なくないと思う。

そんなこんなで知らせるところでだいぶ苦戦してる。自分とその周りに役立てばそれで十分なんだけどね。

これがないと捗らない、僕のKarabiner設定(late 2017)

  1. 1. Karabiner-elements
    1. 1.1. GUI設定 Overview
      1. 1.1.1. Simple Modifications
      2. 1.1.2. Function Keys
      3. 1.1.3. Complex Modification
        1. 1.1.3.1. Change Space to R-Shift (if alone)
        2. 1.1.3.2. Change Delete to R-Ctrl (if alone)
        3. 1.1.3.3. Change L-Cmd + R-Opt to L-Cmd + Space
        4. 1.1.3.4. Change L-Opt + R-Opt to L-Opt + Space
        5. 1.1.3.5. Change L-Opt to TAB (if alone)
        6. 1.1.3.6. Change R-Opt to ESC (if alone)
        7. 1.1.3.7. コマンドキーを単体で押したときに、英数・かなキーを送信する。
        8. 1.1.3.8. Change FN1 to (, Shift + FN1 to <
        9. 1.1.3.9. Change FN2 to ), Shift + FN2 to >
    2. 1.2. JSON設定ファイル

昨年末から続いてる極まりつつある入力環境シリーズ、Karabiner編。
macOSユーザの大半が使ってるであろう、Karabiner(-elements)というキーボードセッティングユーティリティの設定のお話。ここの設定はもはや無いと使えないレベル。

Karabiner-elements

macOS Sierra以前にKarabinerというツールがあって(それ以前はKeyRemap4macbookという名称だった)。Sierraで内部的に大きく変更があって、簡易的な代替としてKarabiner-elementsが生まれた背景がある。その後アップデートを繰り返し今では以前のKarabinerにひけを取らない、もしくは以前よりも柔軟な設定ができるユーティリティとして生まれ変わっている。

で、もちろんGUIから設定もある程度できるんだけど、内部的にはJSONで設定ファイルが書かれている。さらに柔軟な設定となるとJSONを直接編集する方法になる。なので今回はGUI部分はさっと紹介に留めてJSONをメインで。というより、設定JSONさえ入れればすぐにその設定を使えるので良い。(Karabiner時代は独自のxmlだったので以前よりやりやすくなったと思う)

僕の場合、外付けキーボードを使っていて、そちらでファームウェアレベルでキーリマップはできるものの、外してノートのキーを直接叩く機会もあるので、共通する設定はKa rabiner-elements側で行なっている。また、僕の設定はかなりErgoDox特化の設定でもあるのでご注意を。

GUI設定 Overview

Simple Modifications

Caps LockCtrlにしているだけ。Caps Lockが無いと大変な人って多数派なんだろうか疑問である。システム環境設定側でもできるけど、いろいろ絡めるとこちらで設定するのが良い。

Function Keys

基本的に叩かないのでわりとどうでもいい。デフォルト。すごい偏見だけどWindows使ってた人ってFunctionキー好きだよね。

Complex Modification

Change Space to R-Shift (if alone)

SandS用。SandSとはSpaceShiftキーを両立させるキーで、単体で押したらSpace、他と組み合わせるとShiftになるようなキーのこと。ちなみに僕の使うErgodoxではDoubleFunctionとして設定できるけど、挙動はKarabinerでやるほうが好みの感じになるのでこちらでやってる。

Change Delete to R-Ctrl (if alone)

これは完全に僕の好み。しかもErgoDox特化。黄金の小指を捨てて鋼鉄の親指にするためのもの。要は親指位置にCtrlキーを持ってきていて、それが単体押しだとDeleteとして動作したらいいよね、って感じ。ちなみにノートのキーボードを直で叩く時は小指が黄金化せざるを得ない。

Change L-Cmd + R-Opt to L-Cmd + Space

Cmd+SpaceでAlfred呼び出しにしてるものをErgoDox使用時とキーボード直の時の差を吸収する設定。直の場合、左親指でCmd、右親指でShiftを叩いてAlfredを呼び出している。が、ErgoDoxのときは左側にSpaceキーがないのでOptキーと組み合わせることで同じ動作をするように。

Change L-Opt + R-Opt to L-Opt + Space

これも上と同様で、Opt+SpaceでOmniFocusのクイックエントリに設定しているから。

Change L-Opt to TAB (if alone)

左のOptを単体で押したらTABとして動作。僕の小指はそんなに長くないし。そしてErgoDox系が素晴しいのは親指の有効活用を目指しているからである。

Change R-Opt to ESC (if alone)

上記同様。

コマンドキーを単体で押したときに、英数・かなキーを送信する。

これは最初からプリセットされているものを読み込んで設定できる。US配列好きの日本ユーザーに割と常識になってる英数、かなキーのエミュレーション。僕の場合、AquaSKKでの設定を使うのであまり出番がないけど一応。

Change FN1 to (, Shift + FN1 to <

ErgoDoxにはb,gキーの右側に特殊キーがある。そこを括弧系の入力に割り当ててる。ErgoDox側でFN1を割り合てて、Karabiner側で実際に入力されるキーを指定。これは本来ならErgoDox側のハードウェア的にやるほうが望ましいけど、ErgoDox側でのShiftを絡めたキー指定が難しいため。

Change FN2 to ), Shift + FN2 to >

上記の逆。h,nの左にも同様のキーがあるので逆の閉じる側の括弧を。余談だけど、その上に配置されたキーは、[]{}を割り当てている。

余談だけどUSキーボード好きのJISキーボード使いずらい派は、括弧のキー配列が横並びじゃなくて縦並びになってるが嫌って人が多いと思ってる。あれはとても直感的じゃない。

JSON設定ファイル

上記までの設定が全部かかれたJSONファイル。ちなみに生成されるのファイルのインデントは4スペースだけど、個人的に見辛いので2スペースにしている。で、つまるところJSONなので、これをGitとかGitHub Gistで管理したりDropboxとSymlinkで同期させたりすると複数端末でも使い勝手が良いよね。

karabiner.json
{
"global": {
"check_for_updates_on_startup": true,
"show_in_menu_bar": true,
"show_profile_name_in_menu_bar": false
},
"profiles": [{
"complex_modifications": {
"parameters": {
"basic.to_delayed_action_delay_milliseconds": 500,
"basic.to_if_alone_timeout_milliseconds": 1000,
"basic.to_if_held_down_threshold_milliseconds": 500
},
"rules": [{
"description": "Change ␣ to R⇧ (if alone)",
"manipulators": [{
"from": {
"key_code": "spacebar",
"modifiers": {
"optional": [
"any"
]
}
},
"to": [{
"key_code": "right_shift"
}],
"to_if_alone": [{
"key_code": "spacebar"
}],
"type": "basic"
}]
},
{
"description": "Change ⌦ to R⌃(if alone)",
"manipulators": [{
"from": {
"key_code": "delete_forward",
"modifiers": {
"optional": [
"any"
]
}
},
"to": [{
"key_code": "right_control"
}],
"to_if_alone": [{
"key_code": "delete_forward"
}],
"type": "basic"
}]
},
{
"description": "Change L⌘ + R⌥ to L⌘ + ␣",
"manipulators": [{
"from": {
"key_code": "right_option",
"modifiers": {
"mandatory": [
"left_command"
],
"optional": [
"any"
]
}
},
"to": [{
"key_code": "spacebar",
"modifiers": [
"left_command"
]
}],
"type": "basic"
}]
},
{
"description": "Change L⌥ + R⌥ to L⌥ + ␣",
"manipulators": [{
"from": {
"key_code": "right_option",
"modifiers": {
"mandatory": [
"left_option"
],
"optional": [
"any"
]
}
},
"to": [{
"key_code": "spacebar",
"modifiers": [
"left_option"
]
}],
"type": "basic"
}]
},
{
"description": "Change L⌥ to ⇥(if alone)",
"manipulators": [{
"from": {
"key_code": "left_option",
"modifiers": {
"optional": [
"any"
]
}
},
"to": [{
"key_code": "left_option"
}],
"to_if_alone": [{
"key_code": "tab"
}],
"type": "basic"
}]
},
{
"description": "Change R⌥ to ⎋(if alone)",
"manipulators": [{
"from": {
"key_code": "right_option",
"modifiers": {
"optional": [
"any"
]
}
},
"to": [{
"key_code": "right_option"
}],
"to_if_alone": [{
"key_code": "escape"
}],
"type": "basic"
}]
},
{
"description": "コマンドキーを単体で押したときに、英数・かなキーを送信する。(左コマンドキーは英数、右コマンドキーはかな)",
"manipulators": [{
"from": {
"key_code": "left_command",
"modifiers": {
"optional": [
"any"
]
}
},
"to": [{
"key_code": "left_command"
}],
"to_if_alone": [{
"key_code": "japanese_eisuu"
}],
"type": "basic"
},
{
"from": {
"key_code": "right_command",
"modifiers": {
"optional": [
"any"
]
}
},
"to": [{
"key_code": "right_command"
}],
"to_if_alone": [{
"key_code": "japanese_kana"
}],
"type": "basic"
}
]
},
{
"description": "Change FN1 to (, ⇧ + FN1 to <",
"manipulators": [{
"from": {
"key_code": "international3",
"modifiers": {
"mandatory": [
"left_shift"
],
"optional": [
"shift"
]
}
},
"to": [{
"key_code": "comma",
"modifiers": [
"left_shift"
]
}],
"type": "basic"
},
{
"from": {
"key_code": "international3",
"modifiers": {
"mandatory": [
"right_shift"
],
"optional": [
"shift"
]
}
},
"to": [{
"key_code": "comma",
"modifiers": [
"right_shift"
]
}],
"type": "basic"
},
{
"from": {
"key_code": "international3",
"modifiers": {
"optional": [
"any"
]
}
},
"to": [{
"key_code": "9",
"modifiers": [
"right_shift"
]
}],
"type": "basic"
}
]
},
{
"description": "Change FN2 to ), ⇧ + FN2 to >",
"manipulators": [{
"from": {
"key_code": "international1",
"modifiers": {
"mandatory": [
"left_shift"
],
"optional": [
"any"
]
}
},
"to": [{
"key_code": "period",
"modifiers": [
"left_shift"
]
}],
"type": "basic"
},
{
"from": {
"key_code": "international1",
"modifiers": {
"mandatory": [
"right_shift"
],
"optional": [
"any"
]
}
},
"to": [{
"key_code": "period",
"modifiers": [
"right_shift"
]
}],
"type": "basic"
},
{
"from": {
"key_code": "international1",
"modifiers": {
"optional": [
"any"
]
}
},
"to": [{
"key_code": "0",
"modifiers": [
"right_shift"
]
}],
"type": "basic"
}
]
}
]
},
"devices": [{
"disable_built_in_keyboard_if_exists": true,
"fn_function_keys": [],
"identifiers": {
"is_keyboard": true,
"is_pointing_device": false,
"product_id": 4871,
"vendor_id": 65261
},
"ignore": false,
"manipulate_caps_lock_led": false,
"simple_modifications": []
},
{
"disable_built_in_keyboard_if_exists": false,
"fn_function_keys": [],
"identifiers": {
"is_keyboard": true,
"is_pointing_device": false,
"product_id": 630,
"vendor_id": 1452
},
"ignore": false,
"manipulate_caps_lock_led": true,
"simple_modifications": []
},
{
"disable_built_in_keyboard_if_exists": false,
"fn_function_keys": [],
"identifiers": {
"is_keyboard": true,
"is_pointing_device": false,
"product_id": 628,
"vendor_id": 1452
},
"ignore": false,
"manipulate_caps_lock_led": true,
"simple_modifications": []
}
],
"fn_function_keys": [{
"from": {
"key_code": "f1"
},
"to": {
"key_code": "display_brightness_decrement"
}
},
{
"from": {
"key_code": "f2"
},
"to": {
"key_code": "display_brightness_increment"
}
},
{
"from": {
"key_code": "f3"
},
"to": {
"key_code": "mission_control"
}
},
{
"from": {
"key_code": "f4"
},
"to": {
"key_code": "launchpad"
}
},
{
"from": {
"key_code": "f5"
},
"to": {
"key_code": "illumination_decrement"
}
},
{
"from": {
"key_code": "f6"
},
"to": {
"key_code": "illumination_increment"
}
},
{
"from": {
"key_code": "f7"
},
"to": {
"key_code": "rewind"
}
},
{
"from": {
"key_code": "f8"
},
"to": {
"key_code": "play_or_pause"
}
},
{
"from": {
"key_code": "f9"
},
"to": {
"key_code": "fastforward"
}
},
{
"from": {
"key_code": "f10"
},
"to": {
"key_code": "mute"
}
},
{
"from": {
"key_code": "f11"
},
"to": {
"key_code": "volume_decrement"
}
},
{
"from": {
"key_code": "f12"
},
"to": {
"key_code": "volume_increment"
}
}
],
"name": "Default profile",
"selected": true,
"simple_modifications": [{
"from": {
"key_code": "caps_lock"
},
"to": {
"key_code": "left_control"
}
}],
"virtual_hid_keyboard": {
"caps_lock_delay_milliseconds": 0,
"keyboard_type": "ansi"
}
}]
}

そんなこんなで年も明けてだいぶたつけど、去年末にもあとめた一連の入力環境カスタマイズシリーズはおしまい。
整理するにあたって確認しなおしたのでこれからはあんまり変わることはなさそう。

とはいえ、キーバインドあたりはまだまだ何とかしたい感ある。
装飾キーの押し分けによってスコープを変えたい、例えばCmd単体ならアクティブなウインドウの操作、Cmd+Ctlrならアクティブなアプリの操作、Cmd+Ctlr+Altでグローバルな操作、とか。

そうやりたいのはやまやまなんだけど、デフォルトで設定されてるキーバインドも大事にしたくて、その両方の落としどころが上手く見つからない感じ。

何故僕はTumblrからHexo+Netlifyに移行したのか

  1. 1. Hexoについて
  2. 2. Netlifyについて
  3. 3. Tumblrについて
  4. 4. それでも僕がTumblrを離れたわけ
    1. 4.1. テーマの自作がやや面倒
      1. 4.1.1. TumblrのJavaScriptが避けれない
    2. 4.2. エントリが管理できない
    3. 4.3. Tumblr == リブログ というイメージが強すぎる
      1. 4.3.1. もにょる
  5. 5. じゃあHexo+Netlifyは?
  6. 6. 昔話

細々ながらも長らくブログをやってきまして。つい先日しれっとTumblrからHexoというブログ特化型の静的サイトジェネレータをNetlifyでホストする方法に移行しました。

Hexoについて

ブログ特化型の静的サイトジェネレータは今ではいろいろ豊富で、Jekyllなんかを皮きりにMiddleman、Hugo、Octopress、Gatsbyなどがある。

で、結果的にできることっていうのはどれもそんなに変わらないんだけど、過程としてそもそも動く言語が違う。ということで僕がHexoを選んだのはNode.jsで動くから、っていう理由だけ。特に僕は既存のテーマとか使うのは好きじゃなく自分で作りたい派だから慣れ親しんだPug、Stylusでテーマ作るのもNode.jsのほうがやりやすい。

と、書いて思ったけどわりとテーマ自作って少ないのかな。昔からいろんなブログを転々としてきたけど、いつだってテーマは自作してきた。それが普通だと思ってた。

まあそんなこんなでローカルで開発できてテストできて、デプロイも簡単なHexoにすることに。それにブログ程度、動的な要素はそんなに必要なくて静的で十分事足りるし。

Netlifyについて

静的サイトをホスティングするWebサービス。Git系リポジトリのWebhookからビルド、デプロイできるし、SSL/HTTPSもばっちり。カスタムドメインも使えるし至れり尽せりな上に基本無料(CDNを日本にしたり、パスワードかけたりは有料)。個人の静的サイトならもうNetlifyで全部いいんじゃないかって思う。

もちろんGitベースのソース管理してデプロイするのは開発に関する知識が少し必要だから使うユーザのレベルは少しだけ要求されるけど、逆に言えばその程度しか要求されないのですごく楽。

各エントリの内容はもちろん、テーマや設定系も全部Git管理できるのは本当にいい。それでpushするだけでデプロイ完了。めっちゃ楽チン。

Tumblrについて

僕はTumblr大好きだったし今でも好き。本当、知ってる人の認識が「リブログ専用ブログサービス」みたいな認識なことだけはクソだと思ってるけど、これは日本のユーザコミュニティの問題なのでもうしょうがない。

Tumblrをブログサービスとしてちゃんと見た時、意外にも使いやすい。文章を書くのに必要なフォーマットはあるし、Markdownだってもちろん対応。WebAPIも用意されてるからMarsEditのようなブログ用のアプリで更新できる。

できないのはOGPにテキストタイプの投稿ではOGPにアイキャッチ画像を載せれないぐらい。コメントはdisqus使ったり、関連記事とかも工夫しなきゃいけないけど不可能ではない。

むしろ、なんだかごちゃごちゃしてて無駄な情報が多いなか、Tumblrの主流はシンプルなミニマリスティックな感じはとてもいい。もう一度言うけど、Tumblrはリブログ専用ではない。

そしてリブログがあるが故に拡散能力が高いのもポイント。普通だとRSSとか巡回や検索流入だけだけど、TumblrはDashboardを潜る(Twitterで言えばTimeLineを眺める)人も多い。そしてRTならぬReblogがある。リブログされれば別の人のTumblrに自分の記事が載る。これはなかなか伝播力あるし、リブログがリブログで広がるより一時ソースお自分の記事としてリブログされるのはかなり楽しい。

何度でも言うぞ、Tumblrはリブログ専用サービスじゃねえ。

それでも僕がTumblrを離れたわけ

そんなTumblr好きなのに別れを決意したにはやっぱり理由がある。むしろ感覚的には好きだからこそ今まで使ってきた、に近い。

テーマの自作がやや面倒

テーマは自作できるし、公式ドキュメントをしっかり読んだり、既にあるもののソースを見ればそんな難しくない。1つのテンプレートファイルで分岐でなんとかしてるってのがわかってしまえば簡単。拡張性もそこそこある。

とはいえ、Tumblrの管理画面で操作することも多く、何度も修正を繰り返すのはちょっと難儀。
バージョン管理もないし、手元で書いたソースをコンパイルして圧縮してそれをコピペしてリロードするのはやっぱり面倒。

TumblrのJavaScriptが避けれない

つまりテーマに手を加えるだけじゃAMPが使えない。強制でJSが挿入されるので。まあ無料のWebサービス使っておいてなに言ってんだ、って話ではあるけども。
AMPに対応しようと思ったら外部のサービスを使う必要があるけど、それだと自動生成にしかならないのでリッチなAMP対応ページを作れない。

エントリが管理できない

Web上のエディタにそのまま書くという暴挙なんてしない。とはいえMarsEditでやるしかない。僕はそれでもまだ不満で、エディタは一つでいい。むしろ一つがいい。

どういうことかというと、自分用にフルカスタムしたエディタで書かかないとストレスたまる。補完とか、シンタックスハイライトとか。世にMarkdownエディタはポコポコ生まれるけど、ほんと意味わかんない。エディタは自分でカスタムして、みんなが欲しいのは管理ツールだけだと思ってる。

そういうわけで、Atomで書いてMarsEditにコピペしてポストするのがおっくう。
MarsEditが最近バージョン上がって、アップグレードフィーを要求されたことと、書いたものや下書きをファイルとして管理しにくいというところも大きな要因。

今後他のプラットフォームに移行したり取り回しを考えると、.mdで保存しておけないは苦痛

Tumblr == リブログ というイメージが強すぎる

テーマを上手くやれば、このサイトはTumblrです、って言わなきゃわかんないようにはできる。独自ドメインでも運用できるし、事実、特設サイトとか簡単なものならパっとTumblrで作って潰すほうがよっぽどスピーディにできると思う。

名前を出すのは失礼かもしれないけど「Tumblr酒場」なるイベントがあるらしい。集まって飲みながらリブログするイベントらしい。リブログはTumblrの機能の一つであって、それ以上ではない。だからTumblr酒場じゃなくてリブログ酒場と名乗るべきだと思う。もう一度言うぞ、Tumblrはリブログ専用サービスじゃねえ。

もにょる

今でこそ悟りを開いたけど、苦労して書いた記事がリブログされ、嬉しくて喜んだのもつかのま、リブログ先のほうが人気があって、そこが1次ソースみたいに扱われた時の悲しさ。手柄をかっさらわれたのような感覚。

そんなことが何度かおこってから、まあでも誰にも見られないような陽の目を浴びない扱いよりはマシか、と思いなおしたけどもね。そういうのがあるとやっぱりライトユーザーはここでブログを書こうとは思わないだろうなぁ。ましてや最近はTwitterやInstagramの波及で承認欲求を大人気なく発揮するのはダサいという風潮はなくなりつつあるのだから。

じゃあHexo+Netlifyは?

そんなこんなでTumblrでやりつづけることに鬱屈を感じつつもリブログされた時の楽しさを舐めながら今までやってきて。でもまあエンジニアの端くれとして自分でフルに管理できる環境でやるか、って思ってやってみた。

結果はというと、前半でも書いたけど、めっちゃいい。
いつものエディタでガーッと書いて、コミットしてプッシュしたら新しい記事がデプロイされる。最高。

細かい設定や拡張性もある。余談だけど、過去記事は全部従来のTumblrの記事から移行してURL変わったのは全部リダイレクトしてる。RSSフィードもリダイレクトしてるからパスは変わったけど、登録しなおさなくても問題ないはず(最初だけ過去記事が配信されなおしてしまうけど)。

リブログされやすい環境は手放してしまったものの、書き易さは格段に上がったのが良い。承認欲求はそんなに高くない僕には承認欲求が満たされやすい環境より、書く時のストレスが少ない環境のほうがよっぽど大事。

昔話

僕がブログを始めたきっかけはiBlogというアプリだった。当時のMacユーザ向けに無料で配布されたアプリで、今みたいなブログサービスがほとんどない時代だった。

今風に言えば静的サイトジェネータのGUI版。あれでブログを始めて、なんかカスタマイズして。

そういえば先日、そのころのiBlogコミュニティで今もつながりある友人と会った。僕も今やWebエンジニア、彼はWebサイト制作会社のやってる。当時の話と、二人ともiBlogがなかったら当時のコーディングをあんなにがんばらなかっただろうし、今につながってないよね、なんて話をした。

今思えばiBlogが半手作り感あったからこそ、自分でテーマを作るのは当たり前の感覚になったのかもしれない。

面白いもので、あれから、GoogleBlogger使ってみたりTumblr使ってみた後で、今こうして使い出したのも静的サイトジェネレータ。やってることはGUIからCUIベースに変わっただけで、なんかまた戻ってきた感ある。

そういうわけで、まだ作りが甘いところをちょいちょい直しつつも、新しくなった環境でこれからも細々とブログ書いていきます。(Tumblrはまた独自ドメイン取る前のURLに戻して、別のものとして楽しんでやっていきます)

これがないと捗らない、僕のErgoDoxファームウェア(late 2017)

  1. 1. ErgoDox
    1. 1.1. ErgoDoxEZ
      1. 1.1.1. Kinesisとの使用感比較
      2. 1.1.2. ErgoDoxのキーカスタム
        1. 1.1.2.1. 基本
        2. 1.1.2.2. 親指まわり
        3. 1.1.2.3. 周りのキー
        4. 1.1.2.4. レイヤー系
  2. 2. Karabiner-element Required

昨年末から続いてる極まりつつある入力環境シリーズ、今回はソフト的な設定ではなく外付けキーボードのハードウェア的な設定の話。普段家でも職場でもMacBookProを使っていて持ち運ばない時はErgoDoxEZという外付けキーボードを使っている。これがいろいろ柔軟に設定できるのでその話。

ErgoDox

ErgoDoxという風変りなキーボードを知っているだろうか?以前エンジニア界隈で話題になったけど、左右セパレート型かつ親指周りに多めにキーを配置したのが基本形のキーボードがある。昔からある最強にして変態キーボードと名高いKinesisと似てる使用感がありつつ、左右セパレートを実現している。そして、ファームウェア(押したキーに対する挙動の設定)をキーボード側に書き替えれるので自分の好みの配置にできるのが素晴しい。

ErgoDoxEZ

ErgoDoxとは半自作キーボードであり、通常はキットで自分ではんだ付けして組み立てる。が、組み立て済みのセットとして、ErgoDoxEZというのもある。こちらはフルセットかつ作りもしっかりしていて、保証もある。逆にキットで自作するほうが色とか本当に自分好みにできる。

そんなわけで僕はEZのほうを使ってるけど、一度トラブルがあったもののすぐに、本当にすぐに交換対応してくれたので保証があって良かったなぁ、と思う。そして備え付けの角度調節用の足も良い感じ。EZでもCherry MX軸の中のいくつかから軸は選べる(僕は赤軸使用。欲を言えばピンク軸が欲しかった。)し、キーキャップはEZの販売サイト以外でも手に入る。

もちろんキットで自作するよりは高く付くものの、保証や出来を考えるとEZも値段的バリューは悪くないと思う。特に台湾から発送なので送料はキットよりも安い(キットはヨーロッパから)。ドル立てとユーロ立ての為替も関係してくるけど。

Kinesisとの使用感比較

ErgoDox以前はKinesisユーザだったので、簡単に思い出せる範囲内で使用感を比較してみよう。

打鍵感は、今のErgoDoxのほうが良いかな。でもKinesisの時はデフォルトの茶軸、今のErgoDoxは好みに合った赤軸を使ってるからな気がする。正直、Kinesisの赤軸と比較しないとなんとも。あとはキーキャップ替えたりO-ring噛ませたりでタッチは変わってくる。

キーキャップはKinesisは専用で選択の余地がないけど、エルゴノミクスデザインが素晴らしい。手の自然な形状に合うような気がする。ErgoDoxはキーキャップの選択の余地があるものの、一つ一つが専用の傾斜があるわけではない。ただし、足などでキーボード全体の傾斜を整えれば結構肉薄できてると思う。

パームレストはErgoDoxは必須だと思う。専用がもちろん良いけど、下で紹介してるような安価な物でも十分。Kinesisは本体がパームレストも兼ねてるし、固いなら付属のパッドをくっつければ十分だと思う。

大きさと置き場所的には断然ErgoDoxのほうが上。セパレート型は慣れると素晴しい。左右の手の間隔を自分で決められるのは思ってる以上にデカい。その証拠に僕の自宅のイスの写真を載せておこう。もはやキーボードは机に置く必要すらない。Kinesisだとこうは行かず机に置かざるを得ない。しかも単体の大きさがそれなりにあるのでいろいろ物理的制約が出てくる。ErgoDoxだとセパレートなので左右の間にMacBookProを挟んで(僕の職場仕様はこのスタイル)も全く問題ない。

キーカスタマイズはErgoDoxのほうがやや上かな。ファームウェアを自分でビルドして書き替えなきゃいけないものの、ビルドはDockerで、書き替えは専用ソフトでやっちゃえば良いので一度やれば変更はそんなに大変じゃない。最初はちょっと戸惑うけど。ただそのぶん、柔軟性は随一。Kinesisのキー設定も必要十分でキーの入れ替えはもちろんマクロ登録もできる。加えてレイヤーにも分けれるのでErgoDoxにもひけを取らない。

ErgoDoxのキーカスタム

ここでようやく本題。とりあえずソースを。

// Netable differences vs. the default firmware for the ErgoDox EZ:
// 1. The Cmd key is now on the right side, making Cmd+Space easier.
// 2. The media keys work on OSX (But not on Windows).
// make clean && make keyboard=ergodox subproject=ez keymap=my-keymap
#include "ergodox_ez.h"
#include "debug.h"
#include "action_layer.h"

#define BASE 0 // default layer
#define MOVE 1 // Cursol keys and Mouse Keys
#define CALC 2 // Keys like a calculator
/* period of tapping(ms) */
#ifndef TAPPING_TERM
/* #define TAPPING_TERM 200 */
#define TAPPING_TERM 75
#endif

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 0: Basic layer
*
* ,-----------------------------------------------------. ,-----------------------------------------------------.
* | ESC | 1 | 2 | 3 | 4 | 5 | `~ | | '" | 6 | 7 | 8 | 9 | 0 | \| |
* |--------+------+------+------+---------+-------------| |------+------+---------+------+------+------+--------|
* | TAB | Q | W | E | R | T | [ | | ] | Y | U | I | O | P | '" |
* |--------+------+------+------+---------+------| { | | } |------+---------+------+------+------+--------|
* | LCtrl | A | S | D | F | G |------| |------| H | J | K | L | ;: | -_ |
* |--------+------+------+------+---------+------| |------+---------+------+------+------+--------|
* | LShift | Z | X | C | V | B | ( | | ) | N | M | , | /? | += |
* `--------+------+------+------+---------+-------------' `-------------+---------+------+------+------+--------'
* | ~L2 | ~L1 | Left | Right|LGui/Eisu| |RGui/Kana| Up | Down | ~L1 | ~L2 |
* `-------------------------------------' `-------------------------------------'
* ,-----------------. ,-----------------.
* |LCtrl | LAlt | | RAlt | RCtrl |
* ,------|--------|--------| |--------+--------+------.
* | | | Tab | | Tab | | |
* | Space| Del |--------| |--------| BKspc |Enter |
* |LShift| LCtrl |LAlt/TAB| |RAlt/ESC| | |
* `------------------------' `------------------------'
*/
// If it accepts an argument (i.e, is a function), it doesn't need KC_.
// Otherwise, it needs KC_*
[BASE] = KEYMAP( // layer 0 : default
// left hand
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_GRV,
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_LBRC,
KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G,
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_JYEN,
// MO(CALC), MO(MOVE), KC_LEFT, KC_RGHT, MT(MOD_LGUI, KC_LANG2),
MO(CALC), KC_LALT, KC_LEFT, KC_RGHT, KC_LGUI,
KC_LCTL, KC_LALT,
KC_TAB,
// MT(MOD_LSFT, KC_SPC), MT(MOD_LCTL, KC_DEL), MT(MOD_LALT, KC_TAB),
KC_SPC, KC_DEL, KC_LALT,
// right hand
KC_QUOTE, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSLS,
KC_RBRC, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_QUOT,
KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_MINS,
KC_RO, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_EQL,
// MT(MOD_RGUI, KC_LANG1), KC_UP, KC_DOWN, MO(MOVE), MO(CALC),
KC_RGUI, KC_UP, KC_DOWN, KC_RALT, MO(MOVE),
KC_RALT, KC_RCTL,
KC_TAB,
// MT(MOD_RALT, KC_ESC), KC_BSPC, KC_ENT
KC_RALT, KC_BSPC, KC_ENT
),
/* Keymap 1: Media and mouse keys
*
* ,--------------------------------------------------------. ,--------------------------------------------------.
* | TRANS | F1 | F2 | F3 | F4 | F5 | | | Power| F6 | F7 | F8 | F9 | F10 | F11 |
* |--------+------+--------+--------+--------+-------------| |------+------+------+------+------+------+--------|
* | TRANS | | | MsUp | | | WhUp | | WhUp | | | UP | | | F12 |
* |--------+------+--------+--------+--------+------| | | |------+------+------+------+------+--------|
* | TRANS |WhLeft| MsLeft | MsDown | MsRght |WhRght|------| |------| | Left | Down | Right| | VolU |
* |--------+------+--------+--------+--------+------|WhDown| |WhDown|------+------+------+------+------+--------|
* | TRANS | | | | | | | | | | | | | | VolD |
* `--------+------+--------+--------+--------+-------------' `-------------+------+------+------+------+--------'
* | TRANS| TRANS| TRANS | TRANS | TRANS | | TRANS| TRANS|TRANS | TRANS| TRANS |
* `----------------------------------------' `------------------------------------'
* ,-------------. ,-------------.
* | TRANS| TRANS| | TRANS| TRANS|
* ,------|------|------| |------+------+------.
* | | | TRANS| | TRANS| | |
* | Lclk | Rclk |------| |------|MsAcl2|MsAcl1|
* | | | WhClk| |MsAcl0| | |
* `--------------------' `--------------------'
*/
// Cursor Keys and Mouse Keys
[MOVE] = KEYMAP(
KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_MUTE,
KC_TRNS, KC_NO, KC_NO, KC_MS_U, KC_NO, KC_NO, KC_WH_D,
KC_TRNS, KC_WH_L, KC_MS_L, KC_MS_D, KC_MS_R, KC_WH_R,
KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_WH_U,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_BTN1, KC_BTN2, KC_BTN3,
// right hand
KC_PWR, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
KC_WH_D, KC_NO, KC_NO, KC_UP, KC_NO, KC_NO, KC_F12,
KC_NO, KC_LEFT, KC_DOWN, KC_RGHT, KC_NO, KC_VOLU,
KC_WH_U, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_VOLD,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_ACL0, KC_ACL2, KC_ACL1
),


/* Keymap 2: Keys like a Culculator
*
* ,---------------------------------------------------. ,--------------------------------------------------.
* | TRANS | | | | | | | | | | 7 | 8 | 9 | | |
* |---------+------+------+------+------+------+------| |------+------+------+------+------+------+--------|
* | TRANS | | | UP | | |WhDown| |WhDown| | 4 | 5 | 6 | * | / |
* |---------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | TRANS |WhLEFT| LEFT | DOWN | RIGHT|WhRght|------| |------| | 1 | 2 | 3 | + | - |
* |---------+------+------+------+------+------|WhUp | |WhUp |------+------+------+------+------+--------|
* | TRANS | | | | | | | | | | 0 | 0 | . | + | = |
* `---------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | TRANS | TRANS| TRANS| TRANS| TRANS| | TRANS| TRANS| TRANS| TRANS| TRANS |
* `-----------------------------------' `------------------------------------'
* ,-------------. ,-------------.
* | TRANS| TRANS| | TRANS| TRANS|
* ,------|------|------| |------+------+------.
* | | | TRANS| | TRANS| | |
* | TRANS|TRANS |------| |------| TRANS| TRANS|
* | | | TRANS| | TRANS| | |
* `--------------------' `--------------------'
*/
// act like ten keys
[CALC] = KEYMAP(
// left hand
KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_TRNS, KC_NO, KC_NO, KC_UP, KC_NO, KC_NO, KC_WH_D,
KC_TRNS, KC_WH_L, KC_LEFT, KC_DOWN, KC_RIGHT,KC_WH_R,
KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_WH_U,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS,
// right hand
KC_TRNS, KC_NO, KC_P7, KC_P8, KC_P9, KC_NO, KC_NO,
KC_WH_D, KC_NO, KC_P4, KC_P5, KC_P6, KC_PAST, KC_PSLS,
KC_NO, KC_P1, KC_P2, KC_P3, KC_PLUS, KC_PMNS,
KC_WH_U, KC_NO, KC_P0, KC_PDOT, KC_PEQL, KC_PLUS, KC_PEQL,
KC_TRNS,KC_P0, KC_PDOT, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),


};
enum function_id {
LEFT_BRACE, RIGHT_BRACE
};
const uint16_t PROGMEM fn_actions[] = {
// [13] = ACTION_KEY(KC_LPRN), // FN13 - (
// [14] = ACTION_KEY(KC_RPRN) // FN14 - ) >
};
// #define MY_FN13 KC_LPRN
// #define MY_FN14 KC_RPRN
// #define S(MY_FN13) KC_LABK
// #define S(MY_FN14) KC_RABK
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRODOWN only works in this function
switch(id) {
case 0:
if (record->event.pressed) {
register_code(KC_RSFT);
} else {
unregister_code(KC_RSFT);
}
break;
}
return MACRO_NONE;
};

// Runs just one time when the keyboard initializes.
void matrix_init_user(void) {

};
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {

uint8_t layer = biton32(layer_state);

ergodox_board_led_off();
ergodox_right_led_1_off();
ergodox_right_led_2_off();
ergodox_right_led_3_off();
switch (layer) {
// TODO: Make this relevant to the ErgoDox EZ.
case 1:
ergodox_right_led_1_on();
break;
case 2:
ergodox_right_led_2_on();
break;
default:
// none
break;
}

};

基本

基本はQWERTY配列。外出時などMacBookPro側のキーを叩くこともあるし、自分のじゃないキーボードを触る時に戸惑うのでQWERTYからなるべく外れないように指の互換性をキープ。

親指まわり

ErgoDoxの特徴的な配置の親指周りのキー。ここはKarabiner設定でも紹介するけど、SandS(単体押しがSpace、他のキーと組み合わせるとShift)が大活躍。一番使うところ左にSandSキー、その隣はDelete(Forwerd) OR Ctrl。右はEnterとBackSpace。あとはOptionやTABやESCなど。

ちなみに単体押しと同時押しで違う挙動をさせるのはファームウェアでも設定できるけど僕の場合はKarabinerでやってる。実は厳密な挙動が少し違う。

例えば、単体だとAキー、他のキーと押すとBキーとして動作させたいとする。
ErgoDox DoubleFunctionだと、キーを押しつづけると一定時間後にBキーになる。これだとほぼ同時押しに近いような場合、Bキーとして動作しない。単体の時も一定時間以上の場合はBキーだけが入力される。要はKey-Downの時間が一定以上でKey-Up時に入力されるキーが変わる仕様。もっとわかりやすく言えば、普通に押す時と長押しで変わる、という感じ。

Karabinerの場合、まずBキーとして認識され、一定時間以内に他のキーの入力なく離した場合だけAキーとして認識される。この挙動の場合、同時押ししてもBキーになるし、キーを押したまま組み合わせるキーを迷っていてもBキーのまま。単体で入力する時のKey-downからKey-upの時間はわりと一定に収束するので、その時にだけAキーとして入力されるほうが都合が良い。

すごく細かい話だけど、やってみるとかなり使い勝手が変わってくるので重要。本来ならErgoDox側で設定できるならそちらでやるほうが設定と動くものの整合性というかレイヤー的に理に叶ってるんだけど、この違いはデカいのでしょうがない感。

周りのキー

外側一列と内側一列にあるキー達。左手外側には普通のUSキーボードと同じような感じで特殊キーを配置。右手外側も同じ感じで記号キーを配置。左手内側にはカッコ郡を配置。

具体的に、左手内側上は[,{、右手内側上に],}、左手内側下には独自キー用にFN1を指定、逆にはFN2。そしてこれをKarabinerで(,、),>に割り当てる。これはErgoDoxのファームウェア側だと単押しがすでにShiftと組み合わせる入力の場合、さらにShiftを追加する入力が上手く設定できなかったため。FNキーに設定して一旦逃がしてから、FN1単押しでShift+9Shift+FN1ではShift+,が入力されるように設定して実現させている。

レイヤー系

レイヤーはメイン以外に2つ設定していて、1つは上下左右への矢印キーを直感的にしたものと、マウス操作。もうひとつはテンキー操作。これはKinesisにもあったのでなかなか良い。

ちなみに内側の特殊キーにマウスホイールのエミュレート(つまりスクロール)を割り当ててるけどこれもなかなか良い。

必要ないところはぜんぶ割り当てない設定にしてる。

Karabiner-element Required

シリーズ内別記事でKarabinerカスタマイズを紹介する(してる)けど、上記に書いてあるようにかなり頼ってる部分というか密結合してる。本当はあまりよろしくないとは思いつつも他に手段がない上、使い勝手には替えられないのでしかたなし。

小気味良いSandS入力なしにSKKと親指多用のErgoDoxは実現しえない。

これがないと捗らない、僕のAquaSKKカスタマイズ(late 2017)

  1. 1. AquaSKK
    1. 1.1. そもそもAquaSKKって?
    2. 1.2. AquaSKKの設定について
    3. 1.3. keymap.conf
    4. 1.4. カスタムルール
  2. 2. ついでに

昨年(2017年末)僕がメインで使ってるテキストエディタAtomのカスタマイズ記事を書いたんだけど、付随してAquaSKKの設定も書いておこうと思ってたら年が明けちゃった。
表題は(early 2018)とすべきかもしれないけど、変わってないので関連製を持たせるために(late 2017)で。

AquaSKK

そもそもAquaSKKって?

mac OS用のSKKIME。
これについてはだいぶ前に書いた記事「僕が日本語 IM「SKK」に憑かれた訳」を参照していただければ。

AquaSKKの設定について

AquaSKKはただ単にSKK入力を実現するだけじゃなくて、キーバインドや入力ルールもカスタマイズできる。そのへんを弄くる話。

keymap.conf

キー割り当てのセッティング。これをAtomでのキーバインドと相互に寄せてることで入力に関して割と近い統一性を保つようにしてる。

設定の方法についてはkeymap.confの文法を参照のこと。

今の設定はこんな感じ

###
### keymap.conf
### https://ja.osdn.net/projects/aquaskk/wiki/keymap.conf%E3%81%AE%E6%96%87%E6%B3%95

# ======================================================================
# event section
# ======================================================================

SKK_JMODE ctrl::j||keycode::0x68
SKK_ENTER group::hex::0x03,0x0a,0x0d||ctrl::m
SKK_CANCEL ctrl::g||hex::0x1b
SKK_BACKSPACE hex::0x08||ctrl::h
SKK_DELETE hex::0x7f||ctrl::d
SKK_TAB ctrl::n
# SKK_PASTE ctrl::v
SKK_PING ctrl::l
SKK_UNDO ctrl::/

# ======================================================================
# attribute section(for SKK_CHAR)
# ======================================================================

ToggleKana q
# ToggleJisx0201Kana ctrl::q
SwitchToAscii l||hex::0x1b
# SwitchToJisx0208Latin L

EnterAbbrev /
EnterJapanese Q
NextCompletion hex::0x09
PrevCompletion ctrl::p
NextCandidate hex::0x20||ctrl::f
PrevCandidate x||ctrl::b
RemoveTrigger X

UpperCases group::A-K,M-P,R-Z
Direct group::keycode::0x41,0x43,0x45,0x4b,0x4e,0x51-0x59,0x5b,0x5c,0x5f
InputChars group::hex::0x20-0x7e

CompConversion shift::hex::0x0D||shift::hex::0x20

# ======================================================================
# handle option
# ======================================================================

AlwaysHandled group::keycode::0x66,0x68
PseudoHandled ctrl::0||hex::0x1b

ちょっと解説すると、ベースはAquaSKKのデフォルトを踏襲しつつ、自動補完に関してはEmacsのCtrl+p,nによる上下で送り、戻りをできるようにしつつ、Shift+Enterで補完して変換決定をしてる。これはAtomでやってるAutocompleteとほぼ同様になるように寄せている。

変換候補の送り、戻りもCtrl+b,fで対応するようにしてるけど大概の場合はSpaceを何度か叩くことで問題ないのであまり使ってない。

余談だけどSKKになれると日本語/直接入力の切り変えはSKK側のショートカットで行えるので、USキーボードのようにかなキー、英数キーが無くても全く問題ない。(一応僕はKarabiner-elementsで設定してるけどほとんど使ってない)

カスタムルール

AquaSKKでは日本語入力時の入力に対する出力をカスタムできる設定がある。
設定方法についてはかな変換のカスタマイズをご参照あれ。

簡単に言えば、入力,ひらがな時の出力,カタカナ入力時の出力,半角カナ時の出力を書けば、それぞれ適宜出力されるようになる。これによって、使わない全角入力文字の排除と日本語入力時にも半角英数(記号)の直接入力の両方が実現できる。さらに慣例的にz+何かでよく使われる記号を入力することもできる。これもなかなかありがたい。

ファイルで分割すればチェックボックスでオン/オフが設定できるけど、そもそもオン/オフしたい時がないので1つのファイルに自分用は全部書いて適用してる。注意すべきは文字コードをEUC-JPで保存しなければいけない点。

###
### custom-symbols.rule -- 日本語入力時の記号入力
###

### 日本語で良く使うもの
!,!,!,!
?,?,?,?
~,〜,〜,~
(,(,(,(
),),),)

### FEPベース全角記号
z1,○,○,z1
z!,●,●,z!
z2,▽,▽,z2
z@,▼,▼,z@
z3,△,△,z3
z#,▲,▲,z#
z4,□,□,z4
z$,■,■,z$
z5,◇,◇,z5
z%,◆,◆,z%
z6,☆,☆,z6
z^,★,★,z^
z7,◎,◎,z7
z8,∞,∞,z8
z*,×,×,z*
z+,±,±,z+
z~,≠,≠,z~
z=,≒,≒,z=
z`,※,※,z`
z|,|,|,z|
z\,¥,¥,z\
z{,【,【,z{
z},】,】,z}

### HTML escapes
z&,&,&,z&
zc,©,©,zc
z",",",z"
z',',',z'
z,>,>,z>

### PNBF emacs arrows
zp,↑,↑,zp
zn,↓,↓,zn
zb,←,←,zb
zf,→,→,zf

### コロン/セミコロン
;,;,;,;
:,:,:,:
z;,;,;,z;
z:,:,:,z:

簡単に解説すると、

  • !,?,〜,()についてはちゃんと全角で入力できるようにしてる。
  • Windows用SKK「FEP」で設定されている記号入力をベースにしつつ自分用にカスタマイズしたもの
  • HTMLで使われる記号用エスケープの入力ショートカット
  • Emacsの操作に基づく矢印キー入力(ちなみにHJKLはデフォルトで対応してる)
  • コロン/セミコロンは半角を入力するようにし、zをつけたときだけ全角で入力できるようにする

ついでに

ほとんど関係ない余談だけど、僕はキーボードは変態用として名高いKinesisを経て、今はErgoDox EZを使ってる。US配列なので英数キー、かなキーがないけどAquaSKK使いなので困ったことがない。

これがないと捗らない、僕がカスタムしてるAtom設定(late 2017)

  1. 1. Config
  2. 2. Keymap
  3. 3. Stylesheet

前回の「これがないと捗らない、僕が使ってるAtomパッケージ(late2017)」を受けて、さらに追加でカスタムしてる部分。
つまり前回紹介したパッケージが入ってないと関係ないのもあったり。
あの大量のパッケージ郡とこの必須設定、あと紹介しなくてもいい超個人的設定を足すことで、今の僕の快適環境ができあがる。

ここまでカスタムすると他のエディタで入力しようとは思わないので、最近いろんなMarkdownエディタが増えたりしてもまったく希望に合わないのが残念。というか世間が本当に求めてるのはMarkdownビューワー兼ファイラで、エディタは外部エディタがいいんじゃないか、と思う(僕が欲しい、とも言う)。しかもLintも効かないんじゃあねぇ……

そんなこんなで大掃除ついでに設定の棚卸し第二弾。

Config

基本はPreferencesから設定すればいいと思う。というかそっちから設定してもconfigに反映される。
必須というのは日本語の約物まわりだけ、これだけで日本語入力がかなり快適に。

config.cson
"*":
# デフォルトで入ってるbracket-matherに日本語の括弧系も追加
"bracket-matcher":
autocompleteCharacters: [
"()"
"[]"
"{}"
"\"\""
"''"
"``"
"“”"
"‘’"
"«»"
"‹›"
"「」"
"『』"
"【】"
"()"
]
# custome-title用設定
core:
titleBar: "custom-inset"
"custom-title":
template: "<%= projectName %><% if (relativeFilePath) { %> - <%= relativeFilePath %><% } else { %> - <%= fileName %><% } %> <% if (gitHead) { %> [<%= gitHead %>]<% } %> - Atom"
# editor内の設定
editor:
# 文字として扱わないものにデフォルト以外の記号と日本語約物を追加
nonWordCharacters: "/\\()\"':,.;<>~!@#$%^&*|+=[]{}`?-…_、。!?「」『』【】()・”’‘~"
"toggle-quotes":
# バッククォートを追加
quoteCharacters: "\"'`"

Keymap

一部抜粋のなのでこれをこのまま使うと他のとコンフリクト起こす可能性があるので、参考程度に。
基本はEmacsのキーバインドをベース。
ただ、修飾キー周りが煩雑として特にルールもないので最近ちょっと困ってる。
なるべく各アプリやOSのデフォルトキーバインドに寄せたいが、
そのあたりのルールも明確に基準があるわけでもなく、
かといって修飾キーベースで操作単位のスコープにしたい、という思いが上手く噛み合わなくて歯痒い。

ここに書いてある以外にも大量に設定してるけどわりと良く忘れてしまうのでなんとかしたい。

keymap.cson
# for all
# ------------------------------------------------------------
'body':
# ctrl-tabによるタブ変更順を設定
'ctrl-tab ^ctrl': 'unset!'
'ctrl-tab': 'pane:show-next-item'
'ctrl-shift-tab ^ctrl': 'unset!'
'ctrl-shift-tab': 'pane:show-previous-item'
# line-jumperによる複数行移動をEmacs的キーバインドにする
'alt-v': 'line-jumper:move-up'
'alt-shift-v': 'line-jumper:select-up'
'ctrl-v': 'line-jumper:move-down'
'ctrl-shift-v': 'line-jumper:select-down'
'ctrl-k': 'editor:delete-line'

# text-editor for editing
# ------------------------------------------------------------
'atom-text-editor':
# Emacsのsubword mode的なキーバインド、キャメルケース等でも単語づつの移動が可能になる
'alt-b': 'editor:move-to-previous-subword-boundary'
'alt-backspace': 'editor:delete-to-beginning-of-subword'
'alt-d': 'editor:delete-to-end-of-subword'
'alt-f': 'editor:move-to-next-subword-boundary'
'alt-shift-b': 'editor:select-to-previous-subword-boundary'
'alt-shift-f': 'editor:select-to-next-subword-boundary'

# text-editor for editing
# ------------------------------------------------------------
# TODO: github-commitview-editor内でmulti-cursorが動かない問題
'atom-text-editor:not([mini])':
# multi-cursor-plusのキーバインド操作をemacベースにして設定
'ctrl-l': 'multi-cursor-plus:mark'
'ctrl-p': 'multi-cursor-plus:move-up'
'ctrl-n': 'multi-cursor-plus:move-down'
'ctrl-b': 'multi-cursor-plus:move-left'
'ctrl-f': 'multi-cursor-plus:move-right'
'ctrl-alt-b': 'multi-cursor-plus:move-to-beginning-of-word'
'ctrl-alt-f': 'multi-cursor-plus:move-to-end-of-word'
'ctrl-a': 'multi-cursor-plus:move-to-first-character-of-line'
'ctrl-e': 'multi-cursor-plus:move-to-end-of-line'
'ctrl-alt-home': 'multi-cursor-plus:move-to-top'
'ctrl-alt-end': 'multi-cursor-plus:move-to-bottom'
'ctrl-shift-p': 'multi-cursor-plus:select-up'
'ctrl-shift-n': 'multi-cursor-plus:select-down'
'ctrl-shift-b': 'multi-cursor-plus:select-left'
'ctrl-shift-f': 'multi-cursor-plus:select-right'
'ctrl-alt-shift-b': 'multi-cursor-plus:select-to-beginning-of-word'
'ctrl-alt-shift-f': 'multi-cursor-plus:select-to-end-of-word'
'ctrl-shift-a': 'multi-cursor-plus:select-to-first-character-of-line'
'ctrl-shift-e': 'multi-cursor-plus:select-to-end-of-line'
'ctrl-alt-shift-home': 'multi-cursor-plus:select-to-top'
'ctrl-alt-shift-end': 'multi-cursor-plus:select-to-bottom'
# Emmet展開(AquaSkk,AutoCompleteの挙動と近づける)
'ctrl-enter': 'emmet:expand-abbreviation'
# snipet展開中のカーソル移動(AquaSkk,AutoCompleteの挙動と近づける)
'tab': 'snippets:next-tab-stop'
'shift-tab': 'snippets:previous-tab-stop'
# atom-notes がeditor内からでも呼べるようにデフォルトを上書き
'cmd-shift-l': 'atom-notes:toggle'

# Stylus記述用
# ------------------------------------------------------------
# Emmet展開
'atom-text-editor[data-grammar~="stylus"]:not([mini])':
'ctrl-enter': 'emmet:expand-abbreviation-with-tab'

# Markdown記述用
# ------------------------------------------------------------
'atom-text-editor[data-grammar="text md"]':
'ctrl-backspace': 'markdown:outdent-list-item'

# Autocompleteによる補完がある場合専用
# ------------------------------------------------------------
'atom-text-editor.autocomplete-active':
# 選択をEmac的上下で可能に
'ctrl-p': 'core:move-up'
'ctrl-n': 'core:move-down'
# Enter:改行, Shift-Enter:補完入力
'enter': 'editor:newline'
'shift-enter': 'autocomplete-plus:confirm'
# Snipet展開中の場合にtabで前後の入力に移動できるように
'tab': 'snippets:next-tab-stop'
'shift-tab': 'snippets:previous-tab-stop'

# Tree view
# ------------------------------------------------------------
'.tree-view':
# toggle-vcs-ignored-filesが気づかずに誤爆するので設定なしにする
'i': 'unset!'

Stylesheet

おそらくテーマにatom-material-uiを使ってないとUI周り、tree-viewとかはほぼやりなおしな気がする。
というか、atom-material-uiのそのへんが気にくわないので直してる感じ。

他は気づきたいものはちゃんと目立たせたりとか。
あまり必要なさそうなものは載せてない。

styles.less
// 全体的なUI設定
// ------------------------------------------------------------
// 全体のフォント設定
atom-workspace {
font-family: 'Noto Sans UI', 'Noto Sans CJK JP', -apple-system,
'BlinkMacSystemFont', 'Hiragino Kaku Gothic ProN', sans-serif;
}
// tree-view, bottom-dock, right-drawerの幅制御
atom-panel-container {
.left {
max-width: 240px;
}
.right {
max-width: 240px;
}
.bottom {
max-height: 240px;
}
}
// Tree-viewの文字サイズ、行間などが納得いかないのでカスタム
.tree-view {
font-size: 0.9rem;
}
.tree-view .full-menu {
padding-left: 4px;
}
.list-tree .list-nested-item > .list-tree > li,
.list-tree .list-nested-item > .list-group > li {
padding-left: 16px;
}
.list-tree.has-collapsable-children .list-nested-item > .list-item::before {
margin-right: 4px;
}
.list-group .icon::before,
.list-tree .icon::before {
margin-right: 8px;
}
.list-tree.has-collapsable-children li.list-item {
margin-left: 14px;
}
.list-tree.has-collapsable-children .list-nested-item > .list-tree > li,
.list-tree.has-collapsable-children .list-nested-item > .list-group > li {
padding-left: 24px;
}
.list-group li:not(.list-nested-item),
.list-tree li:not(.list-nested-item),
.list-group li.list-nested-item > .list-item,
.list-tree li.list-nested-item > .list-item {
line-height: 1.5rem;
}
.list-group .selected::before,
.list-tree .selected::before {
height: 1.5rem;
}

// リガチャのあるフォントに対応(Hasklig)
// ------------------------------------------------------------
atom-text-editor {
text-rendering: optimizeLegibility;
}
atom-text-editor.editor .syntax--string.syntax--quoted,
atom-text-editor.editor .syntax--string.syntax--regexp {
-webkit-font-feature-settings: 'liga' off, 'calt' off;
}
// ファイルやフォルダ、プロジェクト、コマンド検索で使われるミニエディタをカスタム
// -------------------------------------------------------------
atom-text-editor.editor.mini {
font-size: 1.2rem;
color: #fff !important;
padding-top: 0;
line-height: 1.75rem;
}
.tree-view-search-bar .editor.mini {
font-size: 1.2rem;
}
.advanced-open-file .editor.mini {
font-size: 1.2rem;
}
.advanced-open-file li.list-item {
line-height: 1.75rem !important;
font-size: 1rem;
}
// 全角スペースを目立たせる(idegraphic-space)
// ------------------------------------------------------------
atom-text-editor,
atom-text-editor.editor {
.highlight.ideographic-space {
.region:after {
color: #800000;
content: '×';
background-color: #cccccc;
}
}
.line-number.ruby-block-highlight {
background: rgba(215, 0, 0, 0.4);
}

.highlights {
.ruby-block-highlight .region {
background: rgba(215, 0, 0, 0.4);
}
}
}
// 対応する括弧を目立たせる(Bracket-matcher)
// ------------------------------------------------------------
.bracket-matcher .region {
background: rgba(215, 0, 0, 0.4);
border: 1px solid #b71c1c !important;
position: absolute;
}
// コメントが斜体にならないようにする
// ------------------------------------------------------------
atom-text-editor.editor {
.syntax--comment {
font-style: normal;
}
}
// document-outlineがダークテーマでも問題ないように
// ------------------------------------------------------------
.document-outline heading-node.list-nested-item.highlight {
background: rgba(255, 255, 255, 0.061);
}

これがないと捗らない、僕が使ってるAtomパッケージ(late2017)

  1. 1. テーマ
    1. 1.1. UIテーマ
      1. 1.1.1. atom-material-ui
    2. 1.2. シンタックステーマ
      1. 1.2.1. gruvbox-plus-syntax
  2. 2. 共通
    1. 2.1. 選択系、変換、入力補助
      1. 2.1.1. Sublime-Style-Column-Selection
      2. 2.1.2. change-case
      3. 2.1.3. editorconfig
      4. 2.1.4. expand-region
      5. 2.1.5. highlight-column
      6. 2.1.6. highlight-line
      7. 2.1.7. highlight-selected
      8. 2.1.8. line-jumper
      9. 2.1.9. lines
      10. 2.1.10. toggle-quotes
      11. 2.1.11. toggler
      12. 2.1.12. trailing-semicolon
      13. 2.1.13. trailing-spaces
      14. 2.1.14. sequential-number
      15. 2.1.15. show-ideographic-space
      16. 2.1.16. symbols-tree-view
      17. 2.1.17. tabs-to-spaces
      18. 2.1.18. todo-show
      19. 2.1.19. multi-cursor-plus
      20. 2.1.20. pigments
      21. 2.1.21. regex-railroad-diagram
      22. 2.1.22. autocomplete-paths
    2. 2.2. ファイル、タブ、ペイン操作系
      1. 2.2.1. atom-fuzzy-grep
      2. 2.2.2. split-diff
      3. 2.2.3. advanced-open-file
      4. 2.2.4. douglas
      5. 2.2.5. expose
      6. 2.2.6. hey-pane
      7. 2.2.7. tree-view-filter
      8. 2.2.8. tree-view-git-status
      9. 2.2.9. zentabs
      10. 2.2.10. auto-encoding
      11. 2.2.11. convert-to-utf8
    3. 2.3. Linter系
      1. 2.3.1. linter
      2. 2.3.2. linter-ui-default
    4. 2.4. MiniMap系
      1. 2.4.1. minimap
      2. 2.4.2. minimap-autohider
      3. 2.4.3. minimap-find-and-replace
      4. 2.4.4. minimap-highlight-selected
      5. 2.4.5. minimap-pigments
    5. 2.5. HyperClick系
      1. 2.5.1. hyperclick
      2. 2.5.2. hyperlink-hyperclick
    6. 2.6. 汎用フォーマッタ
      1. 2.6.1. aligner
      2. 2.6.2. atom-beautify
    7. 2.7. その他
      1. 2.7.1. sync-settings
      2. 2.7.2. atom-notes
      3. 2.7.3. atomic-chrome
      4. 2.7.4. platformio-ide-terminal
      5. 2.7.5. tablr
      6. 2.7.6. preview
      7. 2.7.7. auto-update-packages
      8. 2.7.8. busy-signal
      9. 2.7.9. custom-title
      10. 2.7.10. file-icons
      11. 2.7.11. file-types
      12. 2.7.12. goto-definition
  3. 3. 各言語とか用途とか別
    1. 3.1. Git
      1. 3.1.1. gist
      2. 3.1.2. git-blame
      3. 3.1.3. git-plus
      4. 3.1.4. merge-conflicts
    2. 3.2. Markdown
      1. 3.2.1. markdown-preview-enhanced
      2. 3.2.2. document-outline
      3. 3.2.3. markdown-table-editor
      4. 3.2.4. markdown-writer
      5. 3.2.5. toggle-markdown-task
      6. 3.2.6. tidy-markdown
      7. 3.2.7. language-markdown
      8. 3.2.8. linter-textlint
    3. 3.3. JSON
      1. 3.3.1. atom-json-color
      2. 3.3.2. pretty-json
      3. 3.3.3. linter-jsonlint
    4. 3.4. Ruby
      1. 3.4.1. language-haml
      2. 3.4.2. language-slim
      3. 3.4.3. language-rspec
      4. 3.4.4. language-rabl
      5. 3.4.5. linter-rubocop
      6. 3.4.6. linter-erb
      7. 3.4.7. linter-haml
      8. 3.4.8. linter-slim
      9. 3.4.9. autocomplete-ruby
      10. 3.4.10. rubocop-auto-correct
      11. 3.4.11. rufo-atom
    5. 3.5. Rails用
      1. 3.5.1. autocomplete-rails-partial
      2. 3.5.2. rails-db-scheme
      3. 3.5.3. rails-open-rspec
      4. 3.5.4. rspec
      5. 3.5.5. ruby-block
      6. 3.5.6. rails-i18n-plus
      7. 3.5.7. rails-snippets
      8. 3.5.8. rails-transporter
    6. 3.6. JavaScript系(node.jsやメタ言語、フレームワーク含む)
      1. 3.6.1. atom-typescript
      2. 3.6.2. language-vue
      3. 3.6.3. linter-eslint
      4. 3.6.4. linter-coffeelint
      5. 3.6.5. prettier-atom
      6. 3.6.6. aligner-javascript
      7. 3.6.7. js-hyperclick
      8. 3.6.8. vue-hyperclick
      9. 3.6.9. vue2-autocomplete
      10. 3.6.10. gulp-snippets
      11. 3.6.11. jquery-snippets
    7. 3.7. HTML系(メタ言語含む)
      1. 3.7.1. language-jade
      2. 3.7.2. language-pug
      3. 3.7.3. linter-htmlhint
      4. 3.7.4. linter-pug
      5. 3.7.5. tag
      6. 3.7.6. emmet
      7. 3.7.7. indent-tooltip
    8. 3.8. CSS系(メタ言語含む)
      1. 3.8.1. Stylus
      2. 3.8.2. linter-stylelint
      3. 3.8.3. linter-scss-lint
      4. 3.8.4. linter-stylint
      5. 3.8.5. autocomplete-css-with-stylus-support
    9. 3.9. PUML
      1. 3.9.1. language-plantuml
      2. 3.9.2. plantuml-viewer
    10. 3.10. その他の言語系
      1. 3.10.1. language-apache
      2. 3.10.2. language-nginx
      3. 3.10.3. language-lisp

Atomのカスタマイズはパッケージだけじゃないんだけど、とりあえずパッケージ入れないことには始まらないってことで、2017年の棚卸し的に列挙しておこうと思う。

僕の場合、Ruby(Rails)とJavaScript,HTML,CSSを書くことが多いのでそのへんに特化してるカスタマイズになってるはず。使用パッケージが結構多くてそれぞれのパッケージ間でキーマップがバッティングしてたり、スタイルの競合がおこってたりするのでstylesheetとkeymapで弄ってたり、configで特別な設定してたりするけど、それはそれで別の記事に書く。

テーマ

UIテーマ

atom-material-ui

いろいろ設定できるし見やすいので。
ちなみに設定だけだと各種パッケージと上手く行かなかったりするので
ゴリゴリにStylesheet弄ってる。そこについては後日書きます。

シンタックステーマ

gruvbox-plus-syntax

ビビッドな発色も少なく丁度いい感じ。
すごい好きなんだけど、ややメジャーではないらしくエディタのテーマとか選べるツールとかにgruvboxテーマがないのが残念。

共通

選択系、変換、入力補助

Sublime-Style-Column-Selection

SublimeText的な矩形選択(見たままの四角の範囲を選択可能)。

change-case

選択した単語のキャメルケース、スネークケースとかを相互に変換。ケバブケースもドット記法なども幅広く対応しててうれしい。

editorconfig

コーディングフォーマット統一のためのeditorconfigをAtomで対応するためのパッケージ。

expand-region

選択範囲を文字、単語、クォートや括弧で囲んだ要素、と順々に大きくできる。

highlight-column

キャレットのある列をハイライト。

highlight-line

キャレットのある行をハイライト。

highlight-selected

選択してるものと同じものをハイライト。

line-jumper

設定した行数文だけキャレットを一気に移動する。僕はEmacsのページ送り的な送り用途として使用している。

lines

選択した複数行をA-Z順にソート

toggle-quotes

シングルクォートとダブルクォートのトグル変換。configで設定すれば例えばバッククォートも対応できたりする。

toggler

Booleanのような二元的要素をトグル変換。専用のconfigを設定すれば、自分で対応を文字列を増やせる。

trailing-semicolon

行末にセミコロンとカンマをつける。キーバインドで設定すると捗る。

trailing-spaces

行末のスペースを目立たせる。

sequential-number

複数行にわたって連番生成連番の文字列を生成。

show-ideographic-space

全角スペースを目立たせる。わかりやすくStylesheetでカスタムした設定すると良い感じ。

symbols-tree-view

メソッド定義などの一覧をドロワーにツリー型で表示。

tabs-to-spaces

インデントのタブorスペースをトグル変換。ファイル保存時にファイル全体に対して自動実行も可能。

todo-show

プロジェクト内に存在するTODOやNOTEなどのコメントを抽出して表示。

multi-cursor-plus

デフォルトより高機能なマルチカーソル。キーバインドがバッティングしやすいので僕はゴリゴリにkeymapを編集してる。

pigments

カラーコードになってる部分をその色で表示。CSSとか書くなら。StylusやSassの変数も対応してるので重宝する。

regex-railroad-diagram

正規表現をビジュアルで表示してくれる。

autocomplete-paths

path入力のAutocompleteアドオン、でもたまに邪魔なときがある気がする。

ファイル、タブ、ペイン操作系

atom-fuzzy-grep

プロジェクト内をag的なfuzzyGrepしてファイル表示。

split-diff

Paneで分割してDiff表示、見やすい。しかも保存してない状態でもDiffとれるので、長大な文字列とか大きめなオブジェクトを一時的に比較する時も重宝する。

advanced-open-file

ディレクトリ毎に絞り込みでファイルを開ける、フルキーボードで階層ごとに掘っていく場合に便利。

douglas

CLI用リポジトリ管理ツールghqのローカル管理下にあるプロジェクトのショートカット、全てのプロジェクトがGit管理されていればプロジェクトマネージャーはこれだけで十分だと思う。

expose

開いてるタブをmacのexpose的に表示、切り替えできるやつ。

hey-pane

複数paneで分割してる時にアクティブなペインを自動的にほぼ最大化する。フォーカスしたペインに自動的に適用したりもできる。

tree-view-filter

tree-viewで表示しているファイルをインクリメンタルに絞り込む。

tree-view-git-status

tree-view上でgit-statusによる色分け表示する。追加ファイルや変更したファイルとかが視覚的にわかりやすいし、未コミットのファイルもみつけやすい。

zentabs

最大タブ数の設定制御。設定数を越えると古いタブから自動的に閉じていれ変わる挙動になる。設定でピン止めしたファイルや、未コミットファイル除外したりもできる。たくさんファイル開きすぎてわかんなくなっちゃうので。

auto-encoding

エンコーディングの自動判別。

convert-to-utf8

マルチバイトのファイルをutf-8に変換。

Linter系

linter

Linter機能。各言語用は後述。ないと死ぬ。
各言語用のLintは後述。

linter-ui-default

Linter表示用。たぶんLinter入れると入ってくるはず。

MiniMap系

minimap

画面端にコード全体をざっと単純化して見わたせるようなやつを表示。他のパッケージで拡張可能。

minimap-autohider

ミニマップをスクロールしてない時以外は自動的に非表示。

minimap-find-and-replace

ミニマップ内で検索文字列を全てハイライト。

minimap-highlight-selected

ミニマップ内で選択した文字を全てハイライト。

minimap-pigments

ミニマップ内でカラーコード部分をカラー表示。

HyperClick系

hyperclick

コード中のいろんな要素がクリッカブルになる、キーバインドにも対応してるので対象の文字列にキャレットがある時にキー操作でも動作できる。**-hyperclick系のアドオンとかで拡張可能。言語特化のアドオンは、後述の言語別のところで。

URLをクリッカブルにしてデフォルトブラウザで開けるようになる。

汎用フォーマッタ

aligner

オブジェクトの定義とか、連続して変数に値を入れるとき、=:をセパレータとして左右のインデントが揃うようにしてくれるフォーマッタ。言語別のものもある。

atom-beautify

ネストした要素のインデントをうまいこと整形してくれるフォーマッタ。JSONとかも良い感じにやってくれたり。けっこういろいろ対応してる。

その他

sync-settings

GitHubGist経由でAtomの設定を複数端末で同期する、アンインストールしたパッケージも同期できるようになって凄く便利になった、ないと死ぬ。

atom-notes

notational-velocityライクなノートシステムをAtomに組み込み、メモ系の集積ができてそれがカスタマイズした強力な補完機能のAtomで編集できるのは強み。ないと死ぬ。

atomic-chrome

同名のchrome-extensionをGoogle Chrome系のブラウザに入れることで、ブラウザで開いてるページのtextareaを同期的にAtomで編集できるようになる。例えばPull RequestなどMarkdown対応のテキストエリアをAtomで編集できるのはかなり便利。ないと死ぬ。

platformio-ide-terminal

Atom内でターミナルを動作させる。

tablr

CSVエディタ。

preview

プリプロセッサ言語から元言語へコンパイル後の表示。

auto-update-packages

パッケージにアップデートがあったら自動でアップデートする。ちょいちょい自分で確認しなくていいので楽。

busy-signal

ステータスバーに状況表示アイコンをプラス。確かLinterと一緒に入ってくるはず。

custom-title

Atomのウインドウに表示されるタイトルのルールを変更できるようになる。上手く好きなようにファイル名の表示とかにカスタマイズすると地味に便利。

file-icons

ツリービューやタブにファイルのアイコンを表示して視認性を上げる。わりとないと死ぬ。現在もアップデートが盛んでちょいちょい対応アイコン増えてるのがうれしい。

file-types

自動で判別されるファイルタイプのルールをカスタマイズを楽にする。

goto-definition

メソッドの定義元にジャンプできるようになる。

各言語とか用途とか別

Git

gist

GitHubのGistを編集したりアップロードしたり、挿入したり。Gist系はいくつかあったけどこれが一番使いやすかった。

git-blame

行ごとにgitで変更した人を表示する。

git-plus

よく使うgit操作をAtomから直でできる、Atomのコマンド補完が効くので便利、基本的なgit操作はこれだけでいける。わりとないと死ぬ。

merge-conflicts

gitでmergeしようとしてコンフリクトした時の編集サポート。コンフリクトの解消はGitKrakenでやってるけど、一応入れてる。

Markdown

markdown-preview-enhanced

デフォルトのMarkdownプレビューより高機能なプレビュー、TOCやプレゼンモードもあったりする。目次機能もあったり、いろいろと便利。

document-outline

右ドロワーに編集中のMarkdownの目次をページ内リンク付きで表示。

markdown-table-editor

Markdownのテーブル記法編集補助、うまいこと縦のカラム表示を整えてくれる。

markdown-writer

Markdownの全般的な入力補助。とりあえず入れてる。

toggle-markdown-task

Markdownのチェックボックス記法のチェック状態のトグル変換。そんなに使わないけどいちいちキャレットを移動するのが面倒なので。

tidy-markdown

Markdownのテーブル記法の整形や番号付きリスト記法の番号振りなおしなど、フォーマッタ。

language-markdown

デフォルトのものより高機能なハイライタ。

linter-textlint

特に日本語に強い自然言語用のLinter、textlintをAtomで使えるように。Markdown以外でも効く。

JSON

atom-json-color

JSONファイルを階層によってカラーリングを変えて視認性を上げる。

pretty-json

JSONファイルの整形フォーマッタ。

linter-jsonlint

JSON用のLinterアドオン。

Ruby

language-haml

haml用の言語ファイル。

language-slim

Slim用の言語ファイル。

language-rspec

Rspec(Rubyのテストフレームワーク)用の言語ファイル。

language-rabl

Rabl(Ruby用のJSONやxmlに特化したテンプレートサポートGem)用の言語ファイル。

linter-rubocop

Rubocop用のLinterアドオン。

linter-erb

erb用のLinterアドオン。

linter-haml

haml用のLinterアドオン。

linter-slim

slim用のLinterアドオン。

autocomplete-ruby

Ruby用のAutocompleteアドオン。

rubocop-auto-correct

Rubocopルールに従って自動修正。

rufo-atom

Ruby用フォーマッタのrufoをAtomから実行、まだsave時に自動でやってくれたりはしないもよう。JSのprettierな感じになってくれるとうれしいな。

Rails用

autocomplete-rails-partial

Railsのパーシャビュー名のための用Autocompleteアドオン。

rails-db-scheme

schema.rbを参照して自動補完や定義元にジャンプ。

rails-open-rspec

現在開いてるファイルに対応したRspecのファイルを開く。

rspec

Atom上でRspecをrun。

ruby-block

do``if``begenendなどの対になるブロック要素をハイライト。

rails-i18n-plus

Railsのi18n用のAutocompleteとHyperClickアドオンのセット。

rails-snippets

Rails用のスニペット集。

rails-transporter

Model,View,Controllerなど対応するファイル同士を素早く開けるようにする。

JavaScript系(node.jsやメタ言語、フレームワーク含む)

atom-typescript

TypeScriptの言語ファイルか補完や便利機能まで、IDE的サポート。

language-vue

Vue.js用の言語ファイル。

linter-eslint

JavaScript用のLintパッケージであるEslintのAtom-lintアドオン、prettierと連携もできる、ないと死ぬ。

linter-coffeelint

CoffeeScript用のLinterアドオン。

prettier-atom

JSのフォーマッタprettierをAtomから実行、save時に自動実行できる、ないと死ぬ。

aligner-javascript

JavaScript用のalignerアドオン。

js-hyperclick

JavaScript用のHyperClickアドオン。

vue-hyperclick

vue.js用HyperClickアドオン。

vue2-autocomplete

Vue.js用Autocompleteアドオン。

gulp-snippets

gulp用のスニペット集。

jquery-snippets

jquery用のスニペット集。

HTML系(メタ言語含む)

個人的にはPug(Jade)しか書きたくないけど、どうしても使わざるを得ないので他も少々。

language-jade

HTMLプリプロセッサJade用の言語ファイル。

language-pug

JadeはPugになりました。

linter-htmlhint

HTML用Linterアドオン。

linter-pug

Pug用Linterアドオン。

tag

HTMLの閉じタグのショートカットと補完。Pugで書けばいらないんだけどね。

emmet

html,css(プリプロセッサ含む)の強力なスニペット集。

indent-tooltip

Jade(pug)やStylus,Sassのインデントベース記法の環境で現在のキャレットの位置がどの要素のネスト中なのかツールチップで表示。

CSS系(メタ言語含む)

個人的にはStylusしか書きたくないけど、どうしても使わざるを得ないので他も少々。

Stylus

Stylus用の言語ファイルとスニペット集。

linter-stylelint

CSS用のLinterアドオン。

linter-scss-lint

SCSS(SASS含む)のLinterアドオン。

linter-stylint

Stylus用のLinterアドオン。

autocomplete-css-with-stylus-support

Stylus用のAutocompleteアドオン。

PUML

UMLをテキストから表現したもの。細かいレイアウトは難しいもののテキストならgit管理もできるし素早くかけるので覚えてよかった。

language-plantuml

PlantUMLの言語ファイル

plantuml-viewer

PlantUML用のUML図ビューワ

その他の言語系

language-apache

language-nginx

language-lisp

俺の好きなフォントで読ませろ2017年夏決定版

  1. 1. 俺の好きなフォントで読ませろ2017年夏決定版
  2. 2. 俺は俺の好きなフォントで読むぜ
  3. 3. Gist
  4. 4. ちょっと説明とか
    1. 4.1. 使用フォント
    2. 4.2. 上手く表示できないこと
    3. 4.3. 適用範囲
  5. 5. フォントに関してあれこれ

俺の好きなフォントで読ませろ2017年夏決定版

WebサイトにCSSを書くとき、font-familyをどうするか問題。そこに銀の弾丸はない。常々、サイト側がfont-familyを設定するのは装飾的な要素のフォントを使う時以外はエゴだと思ってる。かといってレガシーめなブラウザだとあまり美しくないフォントがデフォルトになってることもまだあるので、やはりfont-familyをある程度設定されるのは今のところは仕方ないと思ってる。

俺は俺の好きなフォントで読むぜ

そもそもだ、あまり読みやすさにこだわってるサイトはそんな多くない気がする。特に日本語のブログ界隈。そこで、もういっそ俺の好きなフォント設定で読ませやがれ、と思ってStylishで殴りつける方法で解決することにした。
註:Stylish:ユーザー側でスタイルシートを設定できるブラウザ拡張。

Gist

/*
Force global font setting
^(?!https?://(.*).?(localhost|192.168.)).*$
*/

@font-face {
font-family: 'Noto Sans';
font-weight: 100;
font-weight: 200;
font-weight: 300;
font-weight: 400;
font-weight: 500;
src: local('NotoSans');
font-display: swap;
}
@font-face {
font-family: 'Noto Sans';
font-weight: 600;
font-weight: 700;
font-weight: 800;
font-weight: 900;
src: local('NotoSans-Bold');
font-display: swap;
}
@font-face {
font-family: 'Noto Sans CJK JP';
font-weight: 100;
font-weight: 200;
font-weight: 300;
font-weight: 400;
font-weight: 500;
src: local('NotoSansCJKjp-Regular'),
local('SourceHanSansJP-Regular'),
local('Noto Sans CJK JP'),
local('Source Han Sans JP'),
url(//fonts.gstatic.com/ea/notosansjapanese/v6/NotoSansJP-Regular.woff2) format('woff2'),
url(//fonts.gstatic.com/ea/notosansjapanese/v6/NotoSansJP-Regular.woff) format('woff'),
url(//fonts.gstatic.com/ea/notosansjapanese/v6/NotoSansJP-Regular.otf) format('opentype');
font-display: swap;
}
@font-face {
font-family: 'Noto Sans CJK JP';
font-weight: 600;
font-weight: 700;
font-weight: 800;
font-weight: 900;
src: local('NotoSansCJKjp-Bold'),
local('SourceHanSansJP-Bold'),
local('Noto Sans CJK JP'),
local('Source Han Sans JP'),
url(//fonts.gstatic.com/ea/notosansjapanese/v6/NotoSansJP-Bold.woff2) format('woff2'),
url(//fonts.gstatic.com/ea/notosansjapanese/v6/NotoSansJP-Bold.woff) format('woff'),
url(//fonts.gstatic.com/ea/notosansjapanese/v6/NotoSansJP-Bold.otf) format('opentype');
font-display: swap;
}
@font-face {
font-family: 'YakuHanJPs';
font-weight: 100;
font-weight: 200;
font-weight: 300;
font-weight: 400;
font-weight: 500;
src: url("https://cdn.jsdelivr.net/npm/yakuhanjp@2.0.0/dist/fonts/YakuHanJPs/YakuHanJPs-Regular.woff2") format("woff2"),
url("https://cdn.jsdelivr.net/npm/yakuhanjp@2.0.0/dist/fonts/YakuHanJPs/YakuHanJPs-Regular.woff") format("woff");
font-display: swap;
}
@font-face {
font-family: 'YakuHanJPs';
font-weight: 600;
font-weight: 700;
font-weight: 800;
font-weight: 900;
src: url("https://cdn.jsdelivr.net/npm/yakuhanjp@2.0.0/dist/fonts/YakuHanJPs/YakuHanJPs-Bold.woff2") format("woff2"),
url("https://cdn.jsdelivr.net/npm/yakuhanjp@2.0.0/dist/fonts/YakuHanJPs/YakuHanJPs-Bold.woff") format("woff");
font-display: swap;
}
*:not([class*="ico"]):not(.fa):not(.DPvwYc):not(i){
font-family: 'Noto Sans', 'YakuHanJPs', 'Noto Sans CJK JP', sans-serif;
-webkit-font-smoothing: subpixel-antialiased;
}
h1, h1 *:not(p), h2, h2 *:not(p), h3, h3 *:not(p), h4, h4 *:not(p), h5, h5 *:not(p),
li, li *:not(p), dd, dd *:not(p), dt, dt *:not(p), th, th *:not(p), td, td *:not(p),
figcaption, figcaption *:not(p), caption, caption *:not(p),
cite, cite *:not(p), label, label *:not(p), select > option {
font-feature-settings: "palt" 1;
}
pre, pre *,
code, code *,
kbd, kbd *,
samp, samp *,
var, var *,
.blob-wrapper * {
font-family: Hasklig, 'Source Han Code JP', monospace !important;
text-align: left;
}
p {
letter-spacing: 0.038em;
word-wrap: break-word;
font-feature-settings: "palt" 0;
}
:lang(en) p {
text-align: left;
}

ちょっと説明とか

使用フォント

以下のフォントを使ってるのでまんま使うならインストールしておいて下さい。

  • 源真ゴシック
  • Noto Sans
  • Hasklig
  • Nasu

完全に個人的な趣味。アルファベットはNoto Sansを使って、日本語は源真ゴシック。コーディングフォントはまだ納得行ってないけど今のところ良く使ってる構成で。こういう和英混植の場合の英字フォントを先に指定して、優先させるハックは好みのフォントを設定しやすいので好き。

もし好きなフォントがあって使いたかったら適宜CSSを修正してください。

上手く表示できないこと

コード表示まわりはいろいろややこしかったりするんですが、上手いこと全称セレクタとか:notセレクタとかで回避したつもりです。が、対応しきれない場合があります(特にアイコンフォント)。

行がぴっしりそろうように、スペースで単語を区切らない日本語を逆手にとったtext-align:justifyハックしてます。故に、日本語だけのときはいいんですが、長めのアルファベットが連続した場合、行の表示が変になることがあります。

適用範囲

頭の部分にコメントアウトしてあるけど、開発する時は当たってほしくないので正規表現でサイトを指定。Stylish側の設定が「正規表現がマッチするサイト」という形なので、正規表現は設定したドメインを「含まないもの」にしておく。お好みで。

フォントに関してあれこれ

一番いいのは、既存のフォントを元に自分の好きなフォントを組み合わせてつくれたら良いんだけど。Font forge使ってやろうとしたけどリガチャ回りとか上手くいかず挫折。そのうちまたチャレンジする。

次に良いのはブラウザ側の標準機能で、英字フォントはこれ、和文にはこれ、monospaceだったらこれ、みたいにできればいい。(現状ある程度は細かくできるけど)。ただし、これだと冒頭で言ったようにサイト側のCSSに設定されてるとアウトなので痛し痒し。これが「font-familyの決定版!」とか言うのにエゴだと良いたくなる元凶。

ただ、せっかく作ったサイトをあまり美しくないフォントで見られるのはたまらねえ、って意見もわからなくない。けど、それこそがエゴなんだけど。そんなことを言う前にletter-spacingline-heightを追いこめ。(上記設定でどちらにも触れてないのは、一律にStylishで汎用的に上書きするのが難しかった為、妥協した。)

OSのデフォルトフォントと、ブラウザのデフォルトフォントと、捨てられない下方互換が生んだ膿なんだろうなぁ。ブラウザのデフォルトフォント問題はそのうち解決されそう。なのでサイト側のCSS最適解がfont-family:sans-serif;だけになるのもそう遠くない日だろう。