Macを外部ディスプレイにつなげた時のWindow配置を記憶したい!
背景
最近の僕は、GoogleChromeのタブを38個とか開いているようです。
Tabs Outliner と Spaces という拡張機能を併用して、 たっくさんあるタブを用途やカテゴリ毎にwindowに分割しているんです。
まあ、ぞれでもWindowは5,6個できるんですけど。
Tabs OutlinerとSpacesのおかげで管理は大分楽になったんですが、困ったことが一つありまして。
問題
普段はMac Bookを外部ディスプレイにつなげて普段作業しているんですよね。Mac Bookのディスプレイと外部ディスプレイ二枚。
会議や相談なんかあれば、外部ディスプレイの接続切ってMac Bookを持っていくわけです。 そして話し終えたら席に戻ってきて外部ディスプレイに接続する。
画面にでてくるのは、SlackやiTerm、そして5,6個重なったGoogle Chrome。
微妙に位置を調整して、ワンクリックで目的のWindowを開けるようにしていたGoogle Chromeの位置を戻すのがもう、面倒でしかたないったらありゃしない。
さすがに、疲れました。
調査
そんなわけで、頼れるGoogle先生に聞いてみたんです。できないかって。
参考になったのは、以下の記事でした。
forget-me-not
は残念ながらアクセス出来ませんでした。まあ2012年の記事だし。
代わりにStay の方を見てみました。
AppStoreで\1,800だったので、即買。
検証
先ほどの StayさえあればもうMBAをサブディスプレイに繋げるのは怖くない を見ながら設定してみました。
2,3回試しました。繋いで、はずして。
Google ChromeのWindow7枚とiTermとSlackだけ個別にstoreしてみました。 Mac Bookを開いたままコネクタを外すと、まあ位置画面に収まります。 そのまま繋げ直してみると、「Restoring windows」と表示されてガチャガチャwindowのサイズや配置が変わっていきます。
結論
なにこれ便利...!
お試しあれ
参考
2015年の振り返り
新年早々いろいろあって振り返ってる余裕が無かったので、それっぽいのをハリボテで。
2015年に書いた記事
当ブログ
8記事!少ない!!
Qiita
2記事!少ない!!
2015年に発表したトーク(public)
www.slideshare.net
www.slideshare.net
www.slideshare.net
www.slideshare.net
4回!ま、まあ...
振り返り
JavaScript一色だなぁ...
ブラウザサイドからNodeJSまで。 ただ、使っているツールや関心の範囲はこの一年でだいぶかわってきたのかなと思う。
フロントエンドツールの開拓、WAFのアーキテクチャ設計、それに関連する各種ライブラリの選定等など、外部モジュールを触るのが多い一年だった。 MVCよくわからんっていう時期から、FluxやReduxを通じてアプリのアーキテクチャを考えていく中で、 単一のライブラリに頼るのも、複数を組み合わせるのもそれなりに模索が必要だと感じているのが年末だった。
2016年の抱負
ツールは揃ってきているけど、いま欲しいものが現状ない。 そういう「何がほしいのか」という部分を自分が適切に理解し、それに即したライブラリを模索・制作していきたいなとは思っている。
年が明けてから、FluxやReduxによって手放そうとしたMVC,DDDを取り戻す方向性を考えている。 技術的にModelとはどういうものか、というより、Model的な考え方をFlux上に載せつつ、効率的に開発できないかと考えている最近。
僕はもともとMVCについての理解が浅かったので、改めて勉強しようかなと思う。
余談
新年早々部屋が半分水浸しになって大変大変つらかったけど、この先は楽しい一年にしていこうとおもったのでした
#gotandajs でトークしてきました
ブログを書くまでがgotandajsだ!ってことで。
gotandajs
五反田や沖縄で JavaScript の勉強する(conpassから引用)会で、AngularJSにFluxとRiotJSを導入したというトークをしてきました。
発表資料
発表について
不足してたなっていう状況を幾つか補足。
- モバイル中心のウェブアプリ(ゲーム)
- JavaScriptを触る人は基本的に僕一人
- 実際にFluxを導入し始めて発表内容の形に持ってくるまで3,4ヶ月くらいかけてる
injector
をRiotJSから参照できるようにするのってどうなの?- 僕一人だから許容してたけど複数人で触るとリスクのほうが高そうなので、ぶっちゃけあんまオススメしない
全体を通して
- 思っていたよりガチで濃ゆい人が集まっていた -- flux, angular, riotを知ってる人が思いの外多くいた -- 他の人のトークも結構濃ゆい話題だった
- Mithrilやreduxといった最近気になっているけど本気で触る余裕がない~なモノとかの話題もあって嬉しい -- トレンドをみんな抑えてる感じで、初回なのにレベル高い
懇親会ネタ
ぱっと思い出せたネタを書き出してみる
- みんな結構、FluxとかReduxとかの設計面で悩んでいる
- Fluxやってると全体でstateを管理したいけど、Reduxみたいに全部管理するのはちょっと
- 程よくComponentとStoreで分散させたい
- ルーターとかどうしてる?
- ReactRouterとか学習コスト高すぎ
- redux-routerは良さそう?
- 最近のライブラリだと何を選ぶ?
- 僕なら初期開発の楽さでAngular
- Vueはすべてがそこそこ良いので安定
- Reactはなんかいろいろめんどくさい、が思想はいい
- Mithrilは
msx-loader
が壊れてて... - などなど...
- テストどうしてる?
- reduxはサンプルをベースに
- fluxとかでロジックはテストし易い
- Reactはテストしやすい...んだろうけど...「「...」」
- Viewのテストのコストが高すぎる
- E2Eでテストしたほうがカバーする範囲広くてリファクタリングとかしやすそう
- 「何」をテストしたいのか? 「ユーザに届ける価値」「どうやってテストすればいいんだー!」
- DIは料理番組
- 下ごしらえ済みの素材を受け取って料理にするイメージ
- だからinjectorをRiotで受け取るのどーなん?って思った
- 静岡アツい
- 次回はG社で
設計の話からビルドシステムの話、他の言語やコミュニティの話、かなり幅広く盛り上がっていた印象
感想
とても楽しい会だった。
なんかみんな似たようなことで悩んでいたり、試そうと思っていたことを試したっていうFBもらえたり、なかなかいい知見を得られたと思う。 コンポーネントのあり方とか、Fluxの設計とかはまだまだ議論の余地もあるだろうし、こういう機会があるのはありがたい。
新しいライブラリも短いサイクルでバンバンでてくるようなJavaScript界隈においてそれぞれが試して意見を交換できる会は貴重だ。
みんなのレベル感も結構近いのでは?と思うくらい懇親会では盛り上がっていたし、本当に楽しかった。
というわけで、大変満足でした。次回も期待します。
お疲れ様でした!
MINILA AIR US67 を購入したのでMac用にカスタマイズしたメモ
商品
Majestouch MINILA Air US67キー 茶軸
設定
caps lock
⇔ctrl
- 鉄板
- [修飾キー設定]
cmd
⇔option
- [修飾キー設定]
caps lock
→cmd
- caps lockなんて要らん
- windows時代の
ctrl
+v|c
の癖が抜けなくてな...
- [ショートカット] 入力ソース/前の入力ソースを選択
cmd
+ESC
- 左手だけで切り替えたいけど大きくブラインドタッチの状態から手を動かしたくないので
所感など
ctrl
+alt
+fn
で接続設定出来るみたいなことが書いてあったけど、結局connect
ボタン使わないと初期設定できなかったESC
⇔~
するかも- キーの差し替えできるの便利
- 押し心地と触り心地が以前使ってたMajestouchと若干違くて新鮮な心地よさがある
指定期間でDOMを出し分けてくれるangular-periodを公開しました
angular-periodとは
AngularJS のDirectiveで、期間を指定するとその 期間前、期間中、期間後でDOMの表示を切り替えてるようにするものです。
例えば、なんかの応募とかで、以下の様なHTMLをテンプレートエンジンやJavaScriptなどを使って出し分けることがある時に便利です。
angularJSを使った一番お手軽なケースとしてはこんなかんじでしょうか。
angular.module("campaign", []) .controller('CampaignCtrl", function () { this.now = new Date().getTime(); this.start = new Date('2015-08-01T00:00:00').getTime(); this.end = new Date('2015-08-31T23:59:59').getTime(); });
<div class="campaign" ng-controller="Campaign as campaign"> <!-- 期間前の表示 --> <div class="form is-previous" ng-if="campaign.now < campaign.start"> <p>○月☓日から応募できます</p> <!-- 期間中の表示 --> <form class="form" ng-if="start <= campaign.now && campaign.now <= campaign.end"> <button type="submit">応募する!</button> </form> <!-- 期間後の表示 --> <div class="form is-after" ng-if"campaign.end < campaign.now"> <p>応募は締め切りました</p> </div> </div>
angular-periodを使えば、以下のように書けます。
angular.module('campaign', ['angularPeriod']);
<div class="campaign" ng-period ng-period-start="'2015-08-01T00:00:00'" ng-period-end ="'2015-08-31T23:59:59'"> <!-- 期間前の表示 --> <div class="form is-previous" ng-period-when="previous"> <p>○月☓日から応募できます</p> <!-- 期間中の表示 --> <form class="form" ng-period-when="during> <button type="submit">応募する!</button> </form> <!-- 期間後の表示 --> <div class="form is-after" ng-period-when="after"> <p>応募は締め切りました</p> </div> </div>
開始と終了を渡すと、その期間の前、中、後のHTMLを選択してDOM Treeに組み込みます。 最も単純なケースではコントローラーすら不要なので、ロジックやテストを大幅に削減できます。
また、angular-periodはリアルタイムな反映及び、setTimeoutの上限値である32bit intを超える値もサポートできるようにしているので、長期にわたる期間であってもある程度は許容されます。
インストール
npm, bowerともに公開しているので必要な方を利用してください。
npm install angular-period
bower install angular-period
日付の指定とパースについて
利用可能な値
上記には文字フォーマットを用いた例を記載しました。 ただ、実際にプログラムする上で文字列だけでは様々な不便なことがあるでしょう。
ngPeriodは Date
オブジェクトに変換可能な値をサポートしています。
具体的には、
- Date
のパース可能な文字列
- Date
オブジェクト
- momentjsなどのDateオブジェクトに渡せるオブジェクト
先ほどの例で、例えばmomentjsを使う場合は以下の様に書けます。
angular.module('campaign', ['angularPeriod']) .controller('CampaignCtrl", function () { this.start = moment('2015-08-01 00:00:00'); this.end = moment('2015-08-31 23:59:59'); });
<body ng-controller="Campaign as campaign"> <div class="campaign" ng-period ng-period-start="campaign.start'" ng-period-end ="campaign.end"> <!-- 期間前の表示 --> <div class="form is-previous" ng-period-when="previous"> <p>○月☓日から応募できます</p> <!-- 期間中の表示 --> <form class="form" ng-period-when="during> <button type="submit">応募する!</button> </form> <!-- 期間後の表示 --> <div class="form is-after" ng-period-when="after"> <p>応募は締め切りました</p> </div> </div> </body>
至ってシンプル。
パースできない値
Dateオブジェクトでパース可能な値はブラウザによって異なります。
パースできない値を渡すと、Dateは Invalid Date
というオブジェクトを返すので、
それをそのままDateとして扱おうとすると、Nanだったり不適切な値になりえます。
困るケースでは、ChromeとSafariで利用可能なDateのフォーマットが異なるという点です。
Chromeは YYYY-MM-DD HH:mm:ss
という値をサポートしていますが、SafariではInvalid Date
が返ってきます。
これは失念すると非常に気づきにくくリスキーで、常にChromeとSafariでの動作確認を要求されるため大変不便です。
angular-periodでは、Invalid Date
になるような値を渡された場合その時点でErrorオブジェクトをthrowするようにはしています。
JavaScriptのDateオブジェクトは非常に複雑かつブラウザ間で挙動が違うので、それを吸収するよりは、すでに実装され安定的に運用されている他のモジュール(momentjsのような)を利用することを推奨します。
まとめ
というわけで結構便利なモジュールを書いたつもりで居るのでどうぞお試しあれ。
node-hariko にクリパラメータによってモックデータを割り振る機能を入れた
欲しかった機能をいれたかったので、 hariko を v1.1.0 に更新しました。
更新内容としては、複数のリクエストをExamplesに設定している時に、リクエストパラメータがマッチするやつを優先的にレスポンスさせるような機能を追加しました。
multipe example
API-Blueprintでは一つのアクションに複数のレスポンスを記載できます。
# GET /messages{?page} + Request /messages (application/json) + Response 200 (application/json) パラメータが無いときは `page=1` としてデータを返す + Body [ /* message arrays */ ] + Request /messages?page=2 (application/json) + Response 200 (application/json) + Body [ /* message arrays */ ] + Request /messages?page=9999 (application/json) + Response 200 (application/json) 存在しないページをしたら空の配列(`[]`)を返す + Body []
モックサーバのレスポンスとの兼ね合い
複数のExampleを定義をした時、リクエストとレスポンスは一つのActionの中に配列で格納されるんだけど、drakov ではキーのマッチングで優先順位を決めてマッチングしてたけど、そんなことよりキーと値が一致したらそいつを優先的に返して欲しい。
上記の例だと
|GET /message|ひとつめ| |GET /message?page=1|ふたつめ| |GET /message?page=2|ふたつめ| |GET /message?page=9999|ふたつめ|
みたいに帰ってきて、9999にリクエストしたら空のレスポンスが帰ってこない!!みたいになる。 いくら、json-outputの機能があるとはいえ、毎回毎回書き換えるのはだるくて仕方ないし、ドキュメント上で明示しておきたい。
クエリパラメータのでマッチングして完全一致したやつを優先的に出力する
node-hariko/resource_spec.js at master · rymizuki/node-hariko · GitHub
こんな感じで。 クエリパラメータの値がMarkdown上で定義されて居て、かつ一致するものがあればそれをレスポンス、 一致するものが無かったら先頭で定義しているものをレスポンスという形にした。
|GET /message|ひとつめ| |GET /message?page=1|ひとつめ| |GET /message?page=2|ふたつめ| |GET /message?page=9999|みっつめ|
を返してくれるようにした。
まとめ
- リクエストとレスポンスを密に連携してよりデバッグしやすい環境を作りました!
todo
- warningsをいまちゃんと出力してないので教えてあげてほしい。
- できれば、コードを示して「どこでwarningsでているのか」をもっとわかりやすくしたい
Introduction to Hariko API Server with API-Blueprint
はい、harikoの紹介です。
harikoとは
harikoとはNodeJS製のAPI MockServerであり、APIドキュメンテーションツールであるAPI Blueprintのエコシステムです。
使い方
npmからインストールして下さい。
npm install -g hariko
harikoはAPI-Blueprintのドキュメントをベースにレスポンスを返すAPI Serverを立ち上げるので、 まずはAPI-Blueprintの仕様に沿ったmarkdownが必要です。
# GET /api/message + Response 200 (text/plain) hello world
適当に、 docs/api/message.md
とかに保存します。
harikoのサーバを立ち上げます。 CLIから以下のように打ち込んで下さい。
hariko -f 'docs/api/*.md'
[INFO] Running Hariko Server ... http://localhost:3000
とshellがレスポンスしたらサーバの実行完了です。
ブラウザとかから http://localhost/api/message を叩いてみてください。
hello world
と表示されるはずです。
harikoの機能たち
詳細はREADME.md とか見て下さいねって感じなんですけど、便利!!!と思って作った機能を幾つか紹介しませう。
markdownファイルの一部除外
drakovになくて地味に不便だったので入れた。 APIサーバに載せたくない一部ファイルを任意で除外するやつ。
glob形式で読み込む奴はブラックリストで弾ける用にしてほしい気持ち。
hariko -f 'docs/**/*.md'\ --exclude 'docs/metadata.md'\ --exclude 'docs/overview.md'
watch
ファイルを監視して、更新したらサーバを再読み込みします。 これは gaze をそのまま使ってます。gruntやgulpやらで使ってる奴。
gruntやらgulpやらのplugin書くときにいちいちreload書くの面倒でしょ?って思ったので。
hariko -f 'docs/**/*.md' -w
proxy
API-Blueprintに定義されていないパスにリクエストが飛んできたら、 指定したサーバにプロキシするオプション。
stubcellの全部のAPIリソースを一斉に移管するのが辛かったので、逐次移行できるようにしたいが為に用意したの。
application → hariko server → stubcell
hariko -f 'docs/**/*.md' --proxy 'http://localhost:8100'
output
これ!!!まじべんりだから!!!べんりだから!!!! 指定したディレクトリにレスポンスデータを吐き出すオプション。
stubcellやeasymockみたいにJSONファイルを弄れば次のレスポンスから結果が変わるという、手動アプリケーションのための仕組み。 リロードしたら全部リセットされるので注意ね♪
hariko -f 'docs/**/*.md' -o 'api/'
verbose
ログレベルをverboseに設定します。 リクエストのデータとか、その辺のデバッグに使うといいかも?
ログ周りは自前だけどそれなりに気を配って書いた気持ち。
hariko -f 'docs/**/*.md' -v
harikoを作った背景
もともと、いまいる会社でSPA (Single Page Application) の開発で、UIファーストを実践していたのですが、どうにもAPIのドキュメンテーションが不足し、サーバとフロントエンドでやりとりの齟齬や過去のリソースについての確認があったり、まあ、ドキュメント欲しいよねって感じでした。(主に僕が
過去に easymock を使っていたのですが、ドキュメントの記法が独特で、メンテナンスもしばらくされていなかったので次のプロジェクトからは、 stubcell を使うようになりました。
どちらのツールも、JSONファイルをレスポンスとして返却してくれるツールだったんですが、 stubcellはJSON5に対応しているし、レスポンス内容を細かく設定できるしで好んで使っていました。
でもさすがに、JSON5だからといってjsonファイルにコメントアウトでドキュメンテーションするのは読みやすいとはいえない状況...
その当時(大体2015年の2月あたり?)からAPI-Blueprintの存在は知っていて、でもドキュメントMarkdownとは言いつつも学習コスト高そうだなぁ、エコシステムもどうなんだろうなぁと思っていたのでした。
時は経ち、「やっぱりドキュメント欲しいね」ってなって、改めてAPI-Blueprintを検証したのでした。
改めて調べてみるとエコシステムはなかなか充実しており、aglio なんかは美しいドキュメントを生成してくれて素晴らしいなぁと思っていたので、ついでに drakov というAPI Mock Serverがあるそうなのでそれも一緒にインストしました。
やーべんりべんり、と思っていたのはつかの間。 drakovを使っていた上で幾つか不便な点が出てきました。
- mdファイルを監視してサーバをリロードしてほしい
- mdファイルを一部除外したい
- 検証用にうん万行のJSONデータを返すようにしたい
- 存在しないAPIはstubcellで立てたAPIにproxyしてほしい
stubcellやらeasymockやらでやっていたファイルを書き換えたら次のリクエストで反映されたJSONが帰ってくるっていう状況は実に効率的だった...
という要望が積み重なってわっと作ったのが hariko というわけです。