kondoumh のブログ

- とあるソフトウェアエンジニアのめったに更新されないブログ -

Visual Studio Code の ChangeLog 用 Extension を作成する

メモ取りを VSCode に移行すると決めたので ChangeLog フォーマット用の環境を整える必要が出てきました。

blog.kondoumh.com

欲しいのは Emacs の組み込み changelog-mode (シンタックスハイライトと項目追加コマンド) 程度の機能です。

Syntax Hilighting

シンタックスハイライトについては、元祖モダンテキストエディタである TextMate で使われていたハイライト定義が後発の Atom や VSCode でもサポートされています。

OrgMode のハイライト定義を頑張って作ってる人はいましたが、ChangeLog 形式のファイルを公開している人は見つかりませんでした。GitHub では ChangeLog が Markdown で書かれている場合が多く必要性が低いと推測されます。そして OSS には ChangeLog がつきものなのでググラビリティも低いです。

ということで、log ファイルのコードハイライトサンプルを参考に作りました。

github.com

後述の VSCode 拡張の開発環境を整えると、Yeomen でジェネレートできる*1のですが、今回は上記のサンプルを編集しました。

changelog.tmLanguage.json: ハイライト定義ファイルの本体です。

{
    "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
    "name": "changelog",
    "patterns": [{
            "include": "#tag"
        },
        {
            "include": "#headline"
        },
        {
            "include": "#list"
        }
    ],
    "repository": {
        "tag": {
            "patterns": [{
                "match": "^\\t(\\*)\\s([^:]+)(:).*",
                "captures": {
                    "1": {
                        "name": "constant.regexp.changelog"
                    },
                    "2": {
                        "name": "markup.changed.changelog"
                    },
                    "3": {
                        "name": "constant.regexp.changelog"
                    }
                }
            }]
        },
        "headline": {
            "patterns": [{
                "match": "^([0-9]{4}-[0-9]{2}-[0-9]{2})\\s+([日月火水木金土])\\s+<([^@]+@[^@]+)>$",
                "captures": {
                    "1": {
                        "name": "markup.deleted.changelog"
                    },
                    "2": {
                        "name": "comment.changelog"
                    },
                    "3": {
                        "name": "entity.name.tag.css.changelog"
                    }
                }
            }]
        },
        "list": {
            "patterns":[{
                "match": "^\\t(\\-)\\s.*$",
                "captures": {
                    "1": {
                        "name": "constant.numeric.changelog"
                    }
                }
            }]
        }
    },
    "scopeName": "source.changelog"
}

日付 + メールアドレスの正規表現を headline、各項目を tag、項目内のリスト要素を list という名前でそれぞれタグ付けして reposiotry に定義し patterns から include しています。

各パターンにマッチしたグループごとに name 属性で色指定をしています。name 属性は TextMate から引き継がれている配色指定のキーになっています。

VSCode の Dark theme ファイル (macOS では下記のパスに格納されています) を VSCode で閲覧しながら適当に指定しました。

/Applications/Visual Studio Code.app/Contents/Resources/app/extensions/theme-defaults/themes/dark_vs.json

ChangeLog は単純な構造なので定義ファイルもコンパクトです。

package.json: ハイライト定義に関するパッケージ情報を定義します。displayName などの属性を設定します。

{
    "name": "changelog-highlight",
    "displayName": "changelog-highlight",
    "description": "A simple extension for changelog syntax highlighting.",
    "version": "0.0.1",
    "publisher": "kondoumh",
    "engines": {
        "vscode": "^1.19.0"
    },
    "categories": [
        "Languages"
    ],
    "contributes": {
        "languages": [{
            "id": "changelog",
            "aliases": ["changelog", "changelog"],
            "extensions": ["ChangeLog"],
            "configuration": "./language-configuration.json"
        }],
        "grammars": [{
            "language": "changelog",
            "scopeName": "source.changelog",
            "path": "./syntaxes/changelog.tmLanguage.json"
        }]
    }
}

language-configuration.json: プログラミング言語固有の設定情報を書きます。ChangeLog は言語というほどのものではありませんが、Emacs の autopair.el のような 自動開閉する bracket の指定があるのでそのまま使うことにしました。

{
    "comments": {
    },
    "brackets": [
        ["{", "}"],
        ["[", "]"],
        ["(", ")"]
    ],
    "autoClosingPairs": [
        ["{", "}"],
        ["[", "]"],
        ["(", ")"],
        ["\"", "\""],
        ["'", "'"]
    ],
    "surroundingPairs": [
        ["{", "}"],
        ["[", "]"],
        ["(", ")"],
        ["\"", "\""],
        ["'", "'"]
    ]
}

launch.json: VSCode 起動時の読み込む設定をします。

// A launch configuration that launches the extension inside a new window
{
    "version": "0.1.0",
    "configurations": [
        {
            "name": "Launch Extension",
            "type": "extensionHost",
            "request": "launch",
            "runtimeExecutable": "${execPath}",
            "args": ["--extensionDevelopmentPath=${workspaceRoot}" ]
        }
    ]
}

以上のファイルを下記構造で ~/.vscode/extensions 配下に置くと VSCode 起動時に読み込んでくれます。

~/.vscode/extensions/changelog-highlight
│  language-configuration.json
│  package.json
│
├─.vscode
│      launch.json
│
└─syntaxes
        changelog.tmLanguage.json

Insert headline Extension

VS Code では日付挿入のような簡単な処理でも Emacs や Vim のように設定ファイルに関数を書いて呼びだすようなことはできず、Extension を作ってインストールするしかないようです。

なんかめんどくさい印象ですが、↓ のチュートリアルに従って Extension のプロジェクトを生成すると案外あっさりできました。拡張を書く障壁を低くするよう頑張ってくれてるみたいです。

code.visualstudio.com

拡張機能は、TypeScript / JavaScript で作成できます*2

以下のように Yeoman と VSCode の ジェネレータを npm で導入し、ジェネレートコマンドを実行すると、コマンドラインで対話的に雛形が作成できます。

$ npm install -g yo generator-code
$ yo code

今回は JavaScript を選択しました。Git リポジトリの初期化も選択すればやってくれます。生成されたプロジェクトを読み込んで、F5 キーを押すかデバッグボタンをクリックすると Extension を読み込んだ状態の VSCode のプロセスが別に起動され、デバッグできます。

package.json: ジェネレート時に指定した displayName などが設定されます。contributes.commands の配列が Extension 使用時にコマンドパレットに表示される コマンド群になります。

{
    "name": "insert-changelog-headline",
    "displayName": "insert-changelog-headline",
    "description": "extension to insert changelog headline",
    "version": "0.0.1",
    "publisher": "kondoumh",
    "engines": {
        "vscode": "^1.19.0"
    },
    "categories": [
        "Other"
    ],
    "activationEvents": [
        "onCommand:extension.insertHeadline"
    ],
    "main": "./extension",
    "contributes": {
        "commands": [{
            "command": "extension.insertHeadline",
            "title": "Insert ChangeLog Headline"
        }]
    },
    "scripts": {
        "postinstall": "node ./node_modules/vscode/bin/install",
        "test": "node ./node_modules/vscode/bin/test"
    },
    "devDependencies": {
        "typescript": "^2.6.1",
        "vscode": "^1.1.6",
        "eslint": "^4.6.1",
        "@types/node": "^7.0.43",
        "@types/mocha": "^2.2.42"
    }
}

extension.js で拡張機能を実装します。ジェネレータではエディタ内で選択されたテキストの文字数をカウントしてポップアップするコードが生成されています。フォーマットした日付とメールアドレスをカーソル位置に挿入するコードを追加しました。

// vscode モジュールを拡張用 API を利用するためにインポート。
const vscode = require('vscode');

// 日付フォーマットのための関数。
function getFormatedDate(date, format) {
    format = format.replace(/YYYY/g, date.getFullYear());
    format = format.replace(/MM/g, ('0' + (date.getMonth() + 1)).slice(-2));
    format = format.replace(/DD/g, ('0' + date.getDate()).slice(-2));
    format = format.replace(/WW/g, ["日", "月", "火", "水", "木", "金", "土"][date.getDay()]);
    return format;
}

// 拡張が activate されるときに実行される関数。
function activate(context) {

    // 拡張が activate される時に出力する診断情報を出力。
    console.log('Congratulations, your extension "insert-changelog-headline" is now active!');

    // 拡張機能の本体を実装して登録する。package.json に設定した commandId にマッチする commandId を指定する必要がある。
    let disposable = vscode.commands.registerCommand('extension.insertHeadline', function() {

        var editor = vscode.window.activeTextEditor;
        if (!editor) {
            return;
        }
        var headline = getFormatedDate(new Date(), 'YYYY-MM-DD WW') + '  <kondoh@local>'
        var selection = editor.selection;

        editor.edit((editorEdit) => {
            editorEdit.replace(selection, '');
            editorEdit.insert(selection.active, headline);
        });
    });

    context.subscriptions.push(disposable);
}
exports.activate = activate;

// 拡張が deactivate される時に実行される関数。
function deactivate() {}
exports.deactivate = deactivate;

デバッグが完了しコードが完成したらプロジェクトフォルダを .vscode 配下にコピーし VSCode を再起動すると extension が読み込まれた状態になります。 コマンドパレットから呼び出して、headline を挿入できるようになります。

f:id:kondoumh:20180112065116p:plain

もちろんパッケージを作って Marketplace で公開することも可能です。

marketplace.visualstudio.com

ということで、VScode で快適に ChangeLog メモを書けるようになりました。

VSCode の Extension は Node.js のエコシステムで開発できるので汎用的なスキルセットが使えて色々高度な自動化ができそうです。

あと Emacs Friendly Keymap を入れるとかなり Emacs です。

marketplace.visualstudio.com

*1:テンプレートに Coloer Theme が用意されています。

*2:ATOM エディタは CoffeeScript でしたね。

ChangeLog メモの移行先を考える

メモ環境をモダン化したい

Trello に移行してみて日常に定着するツールの必要条件としてデスクトップ・モバイルともに使いやすい UI が提供されることが重要だと実感しました。

blog.kondoumh.com

OrgMode は Emacs 使える環境じゃないとダメなので使う頻度が下がってます。

blog.kondoumh.com

日常のメモについては10年以上 ChangeLog メモを Vim や Emacs で書いていて、最近だと Dropbox に Sync しスマホや iPad でもテキストエディタで編集するというスタイルです。

blog.kondoumh.com

ChangeLog メモについては ↓ などをご参照ください。

脱 Emacs もしたいですし、モバイルの UX も向上してほしいです。

移行候補としての Markdown ツール

Markdown エディタはデスクトップでもモバイルでも昔から結構な数ありますが、最近 Electron や React Native (RN) など Web 由来の技術で開発されたクロスプラットフォーム & マルチスクリーンなツールが増えてきました。Electron は Web の洗練された UI とローカルストレージへのデータアクセス機能を提供できます。RN は iOS や Android のコンポーネントを抽象化しているので、各プラットフォームにそれなりの UI を提供可能です。

正月休みにいくつかのツールを試してみました。

  • Joplin
  • Boostnote
  • Quiver

の3つです。

対応プラットフォーム、データフォーマットなど並べてみました。フィーチャーとしてストレージサービス対応、タグ付けなどは、ほぼすべてのツールで利用可能でした。デスクトップ版では執筆に集中するための Zen mode 的な機能もだいたいサポートされてます*1

クロスプラットフォームなコードエディタの最右翼 Visual Studio Code も比較対象としました。VSCode ならではのフィーチャーとしては IntelliSense による入力アシスト、Extension による機能拡張が挙げられます。

Joplin Boostnote Quiver VSCode
macOS
Windows -
Linux -
iOS -
Android - -
Format Plain Text CSON Binary Plain Text
Markdown Preview
Tagging -
ToDo List - -
Zen mode
Storage Service -
Syntax Hilighting
Input Assistance - - -
Extension - - -

以下、個別に見ていきます。

Joplin

Joplin - an open source note taking and to-do application with synchronisation capabilities

個人の OSS プロジェクトのようです。各プラットフォームを網羅しています。

ToDo 用のメモを追加できて進捗を管理できます。ToDo はメモ単位であり、メモ内に ToDo リストは持てません。

Evernote のデータをインポート可能です*2

日本語のテキスト編集にやや難があります。デスクトップもモバイルもかなり荒削りな印象。開発が進めば化けるかもしれません。

Boostnote

boostnote.io

国産の OSS らしいです。デスクトップの UI は結構頑張っている印象です。

メモ内で ToDo リストを管理できます。ToDo リストは OrgMode 形式 (リスト記法と square brackets の組み合わせ - [X]) です。プレビュー側ではチェックボックスとして表示され、チェックをオン・オフすると編集側も同期して更新される双方向バインディングです。メモ内の ToDo 総数と進捗が把握できます。この UI は Trello そっくりです。

Dropbox とのシンクロ方法は以下にありますが、先にデスクトップ版でファイルシステムとして登録しておき、モバイルアプリでシンクロするという手順が必要です。

medium.com

モバイルアプリの編集画面は簡素で保存しないとプレビューできません。RN で実装されています*3。モバイルアプリは新規メモ追加時にアプリがクラッシュするという現象が頻発していました。

ファイル形式としては、CSON *4 形式で Markdown データを内包しています。ファイル名がハッシュ値から機械的に生成されるため、ファイルが多くなってくると他ツールとの相互運用は難しいでしょう。

Quiver

happenapps.com

洗練されたデザインで、現状プロダクトとしての水準は (VSCode を除いて) 一番高い印象です。App Store の有料アプリですが、Free Trial 版が利用できます。

デスクトップは macOS オンリー。モバイルは iOS 版がありますが、編集機能はなく参照オンリーです。

ファイルが独自のバイナリ形式なので、他ツールへの乗換が面倒そうです。Apple 製品だけで生きている人にはよいかもです *5

コードのシンタックスハイライトは、Preview だけでなく 編集画面でも有効になります。

Markdown のシンタックスハイライトは若干バグっています。macOS で時々日本語入力ができなくなるなどの挙動が気になりました。

ツール評価結果

Markdown ツールのデスクトップ版は Quick / Boostnote がよさそうでした。ただ、いずれもモバイルアプリが発展途上な感じで移行がためらわれます。

タグ付け機能もローカルに複数ファイルのメモを溜め込む使い方をしていないので無くても困りません。

ToDo リストも Trello 使ってるので移行のための動機づけにはなりません。

VSCode は JavaScript 書くのに使っていて Markdown エディタとしても並のツールを凌駕しています。もはや ChangeLog のためだけに Emacs を起動しておくのもなんだし・・

結局 Markdown ツールを採用するのではなく常用エディタを Emacs から VSCode に移行することにしました。

Markdown への移行?

Markdown サポートツールが大半なので日常のメモフォーマットとして移行できないか検討しましたが ChangeLog に長年慣れた身には移行が厳しそうでした。

blog.kondoumh.com

Markdown はしっかりした構造の文書を書くためのフォーマットという意識があります。

タイトル
=============
# 見出し1
## 見出し1-1
本文
- 箇条書き1
- 箇条書き2

ChangeLog はソフトウェアアップデート情報を記述するための形式で、日付と更新者、変更内容を簡潔に書くのに適しています*6

ChangeLog 形式:

2018-01-11  Thu. <kondoumh@local>

    * 機能追加1:かくかくしかじか
    - 箇条書きも OK
    * バグ修正1:云々

ChangeLog メモは時系列的にトピックをラベル付けして箇条書きで追記していくスタイルで構造を意識してません。

10年分ぐらいのメモがこの形式で溜まっていて、データ抽出のスクリプト*7などの資産もあり、移行にはそれなりのコストがかかります*8

以上から今回はフォーマット移行しないことにしました。

CLI 命なら

今回検討対象にしていませんが mattn さんの memo コマンドというのがあります。

github.com

設定で editor を指定可能なので Vim じゃなくても使えます。VSCode と統合ターミナルで使うと快適そうです。

qiita.com

サービス専用ツール

Qiita の Kobit やはてなブログアプリなども Markdown ベースのツールですが、各サービスで Markdown を独自拡張していて汎用 Markdown ツールでは publish のイメージがわかりづらいため、専用ツールを利用するメリットはあります*9

ちなみに Kobito はシャットダウンしてしまいました。OSS として残っていますがメンテナンスされていない模様*10

Kobito for Mac / Windowsの提供及びユーザーサポートを終了します - Qiita Blog

まとめ

結局 VSCode で ChangeLog メモという結論になりました。VSCode はモバイル版の提供はありませんが、モバイルでも完成度の高いコードエディタはあるのでデータの共有は簡単。活発に開発されているユーザベースの大きいメジャー OSS であるという点も大きいです。

ChangeLog 形式サポートは何とかする必要がありますが、これについては別エントリーにしたいと思います。

追記: ChangeLog 用 Extension を書くエントリー書きました。

blog.kondoumh.com

*1:メモ取りに Zen mode が必要かという話はさておいて。

*2:Evernote は使ってないので移行先としての評価はしてません。

*3:そもそも RN の事例として知りました。

*4:CoffeeScript 版 JSON

*5:デスクトップ版はおそらくネイティブアプリでしょう

*6:日付の後にメールアドレスが入る謎仕様はこのためです

*7:正規表現モリモリです。

*8:Markdown Parser 使えばいいのでしょうが yak shaving です。

*9:はてなブログ用のアプリはあまり進化しないので、PC / iPad では Web UI を直接使った方が捗りますが。

*10:macOS 版はネイティブアプリでしたが、Windows では Electron 版が提供されてました。OSS 版は Electron 版です。

Tumblr で自分の全投稿の reblog / like 数を把握する

Web で面白そうな記事を見つけた場合、読むのに時間かかりそうなのは Pocket に保存しますが、すぐ読めそうなのはざっと読んで記事内の Tweet アイコンから Twitter に流すことが増えています。

昔は Twitter よりも Tumblr を好んで使っていたので記事内のハイライト的なパラグラフを選んで quote して Tumblr に放流してました。最近は quote の頻度は下がっており、たまに Dashboard を見に行ってポツポツと5, 6個 reblog して閉じるということが多いです*1

reblog.kondoumh.com

Tumblr に quote を放流してると、たまに reblog されまくることがあります。フォロワーの多い人に reblog され、さらに quote over100notes jp などハブアカウントに捕捉されると数が伸びます。reblog にしろ quote にしろ、オリジナルの記事を書いたわけではないので twitter の retweet とは全然別物ですが、自分が放った quote に反応があるとそれはそれで嬉しかったりします。ただ、自分のアーカイブを遡っても、notes(reblog や like) の数はあまり把握できないため、過去にどんな投稿の notes が多かったか振り返ることは簡単にできません。

以前、ストック情報サイトを tumblr のセカンドブログとして構築した時に、Tumblr API をちょっと触ってました。

blog.kondoumh.com

www.tumblr.com

ドキュメントを眺めていると notes_count など反応数も取れそうなので、HTML + JavaScript の簡易な環境でデータ取得を試してみました。確認したのは、Chrome 63.0.3239.132 です。

あらかじめ以下で API Key を取得しておきます。

https://www.tumblr.com/oauth/apps

API の URL、対象の Blog の識別子(ドメイン)、API Key をリクエスト URL 構築用に宣言します。

baseurl = "http://api.tumblr.com/v2/blog/";
domain = "your.tumblr.identifer"
api_key = "yourapikey";

投稿数を取得するには、info メソッドを利用します。

https://api.tumblr.com/v2/blog/your.tumblr.identifer/info

Blog の識別子をパスパラメータ、API Key をクエリパラメータとして指定します。 response を JSON 形式で取得すると、キー 'blog' で取得できるオブジェクトから以下のような情報が得られます。

フィールド 説明
title Blog のタイトル
posts 投稿数
name Blog の短縮名
updated 最近の投稿日時
: :

'posts' フィールドに Blog 投稿数が格納されています。

fetch API で投稿数を取得する例です。

async function getPostCount() {
    var count;
    await fetch(`${baseurl}${domain}/info?api_key=${api_key}`).then(response => response.json()).then(json => {
        count = json['response']['blog']['posts'];
    });
    return parseInt(count);
}

投稿に関する情報は、posts メソッドを使用して取得します。

https://api.tumblr.com/v2/blog/your.tumblr.identifer/posts

パスパラメータに Blog 識別子と投稿タイプ (type : text / photo / quote / link ..etc.) を指定します (投稿タイプは省略可能)。クエリパラメータとして API Key の他に reblog_infonotes_info という bool 値を指定する必要があります。一度に取得できる投稿情報は20件なので、取得開始位置を表すクエリパラメータ offset を指定して繰り返し取得します。投稿は投稿日時の降順で取得できます。

クエリパラメータ 説明
reblog_info reblog 情報を取得するか指定
notes_info notes(reblog や like) 情報を取得するか指定
offset 投稿の取得開始位置

reblog_info を指定すると reblog 情報として、reblogged_root_name が取れます。これが実はオリジナルの投稿者 (blog 短縮名)で、この値が取得できない場合、それは自分の投稿ということになります*2notes_info を指定すると投稿に対する反応 (reblog や like) 数 note_count を取得できます。

投稿情報を取得する関数のコード例です。引数には type (投稿タイプ:空文字だと全タイプを取得)、offsetminCount (反応数の閾値) を指定するようにしています。簡便のため取得したデータはその場で CSV としてレンダリングしてます。

function fetchPosts(type, offset, minCount = 0) {
    fetch(`${baseurl}${domain}/posts/${type}?notes_info=true&reblog_info=true&offset=${offset}&api_key=${api_key}`)
        .then(response => response.json()).then(json => {
            $("#offset").html(`offset:${offset}`);
            $.each(json['response']['posts'], function() {
                if (!this['reblogged_root_name'] && parseInt(this['note_count']) >= minCount) {
                    $("#posts").append(`${idLink(this['id'])},${this['date']},${this['type']},${this['slug']},${this['note_count']}<br />`);
                }
            });
        });
}

メインの処理では、投稿数取得のコールバックでループを回して全投稿分の処理を行います。1回の呼び出しごとに 500ms のスリープを入れています。

$(function() {
    getPostCount().then(count => {
        var offset = 0;
        while (offset <= count) {
            fetchPosts('', offset, 3);
            offset += 20;
            sleep(500);
        }
    });
})

僕は 2008 年頃から Tumblr を始めていて、2017年1月6日時点で投稿総数 6562 件でした(ほとんどがフォローしている人の投稿の reblog です)。測定してませんが全件分処理するのに体感で3分程度でした。

reblog じゃない自分が投稿した中で、3件以上反応があったものをタイプ別に集計すると以下のようになりました。

type post
link 7
photo 36
quote 126
text 5
video 4

やはり quote が母数も多いし、数が多かったです。上位結果は以下のようになりました。

quote:

post_url date note_count
http://reblog.kondoumh.com/post/116903557247 2015-04-20 2072
http://reblog.kondoumh.com/post/128707132367 2015-09-09 901
http://reblog.kondoumh.com/post/101674369492 2014-11-03 797
http://reblog.kondoumh.com/post/100990796202 2014-10-26 567
http://reblog.kondoumh.com/post/125576816117 2015-08-01 337
http://reblog.kondoumh.com/post/113365328582 2015-03-11 304
http://reblog.kondoumh.com/post/92392064267 2014-07-21 224
http://reblog.kondoumh.com/post/78287627384 2014-03-02 209
http://reblog.kondoumh.com/post/59828448393 2013-08-31 168
http://reblog.kondoumh.com/post/86791028732 2014-05-25 112
http://reblog.kondoumh.com/post/39637473249 2013-01-04 101

photo:

post_url date note_count
http://reblog.kondoumh.com/post/126011762237 2015-08-06 110
http://reblog.kondoumh.com/post/105334116637 2014-12-16 107
http://reblog.kondoumh.com/post/165475223402 2017-09-18 74
http://reblog.kondoumh.com/post/62335157286 2013-09-26 74
http://reblog.kondoumh.com/post/153985233752 2016-12-03 71
http://reblog.kondoumh.com/post/62874741172 2013-10-02 61
http://reblog.kondoumh.com/post/119751530162 2015-05-24 59
http://reblog.kondoumh.com/post/96782854287 2014-09-06 56

photo は天体ものが多い感じでした。

*1:Twitter でもほぼ RTer と化していますが。

*2:投稿の 'author' が使えればいいのですがなぜか取れないので API Document には載ってない非公式な方法でしのぎました。

2017 ふりかえり

Job

昨年から引き続き Java EE による業務アプリフレームワーク開発プロジェクト。メンバー候補の面談、タスクアサイン、スコープと仕様の調整、成果物レビュー、テストの取り纏め・・・など雑多にやっています。設計・実装はやってません。来年もしばらく続きそうです。

Java EE は Oracle から Eclipse Foundation に仕様策定が移管されました。

blogs.oracle.com

デファクトである Spring よりかなり存在感薄い Java EE ですが、今後採用が増えていくのでしょうか?

Writings

ブログ以外では特に執筆活動はしてません。

自社のサイトリニューアルにともない、「システム開発地図」の過去記事が再録されました。

喋っただけですが ITpro さんから「すごい設計書」というテーマでシステム開発地図の取材を受け、紹介記事が掲載されました。何社かの事例の一つです。

itpro.nikkeibp.co.jp

「すごい設計書」は特集記事として来年日経の雑誌に掲載されるそうです。

Gadgets

今年は Bluetooth イヤホンをリニューアルしたぐらいでした。

scrapbox.io

Moto 360 2nd Gen は金属アレルギーが治まらず装着するのをやめました。文字通り肌に合わないみたいです。

scrapbox.io

Nexus 6P は購入後2年経過しヘタってしまったバッテリーを交換して継続利用。

scrapbox.io

OS アップデート対象から外れたので Android 9 以降は提供されないことが確定しました。

Google 依存が高いのと Material Design 気に入ってるので電話は Android 続けたいですが iPhone X のフォームファクタで 4/4.7 inch 系列がリニューアルされたら回帰しそうです。

MacBook Pro Early 2015 も3年近く使ってます。外に持ち出すことはほとんどなく、リビングでラップトップ、書斎で外部ディスプレイ繋いで・・と自宅利用がメインです。

scrapbox.io

モバイル用のラップトップは定期的に欲しくなります。

GPD Pocket 的小型マシンは昔から好きで Libretto とか愛用してました。スマホの DNA を受け継ぐ Snapdragon 搭載 Windows PC という新しいジャンルが登場するようなので、オワコン Atom じゃなく Snapdragon 搭載機としてリメークされたら欲しいかも。

japanese.engadget.com

ただ、iOS on iPad が進化していけばモバイルで Windows を使う必然性はあまりなくなりそう。

blog.kondoumh.com

Service / Software

Trello

blog.kondoumh.com

すっかり日常に定着しました。カード内のチェックリストも便利で、ToDo 管理としての OrgMode は使わなくなりました。Emacs 依存が減りつつあります。

Scrapbox

今年はなぜか情報共有系のサービスが色々出てきてました。その中では頭一つ抜けてる感じ。

blog.kondoumh.com

かなり気に入ってます。WYSIWIG なので気軽に書けて書いたものがタグやリンクで繋がって行く感じが楽しいです。発想支援ツールとしても機能すると思います。

Dropbox Paper

paper.dropbox.com

Dropbox のアカウントで利用できる共同編集可能な Wiki システム。Slack との連携機能があります。これも WYSIWYG。けっこう洗練された UI。Google Document よりライトに使える感じです。

kibela

kibe.la

Wiki と Blog をチーム内で共有できるサービス。Qiita Team 的な感じでしょうか。サインアップして1人 kibela してます。

Mastodon

github.com

今年前半話題になったセルフホスティングな Yet Another SNS システム。数多くのインスタンスが立ち上がりました。個人的には全然使ってませんが、コミュニティ醸成に適したプラットフォームなんだろうなと思います。

dev.to

dev.to

今年終盤レンダリングが超速いと評判になった Qiita 的サイト。PWA(Progressive Web Apps) で構築されています。

PWA は Twitter、Pinterest などの大手サービスも対応していて、かなり流行ってる印象です。Android だとネイティブアプリと同等な扱いだし Windows の UWP (Universal Windows Platform) でもサポートされるようになるみたいです。

www.windowscentral.com

Electron でクロスプラットフォームなデスクトップアプリを提供するのは流行りましたが Web サイトが独自ウィンドウで動く程度のアプリが多いため PWA のデスクトップ進出で状況が変わるでしょうか。UWP に関してはこれまで鳴かず飛ばずだし、スマホアプリをデスクトップで動かすだけだと微妙だろうなと思います。

Web ブラウザ

リニューアルされた Firefox。軽くていい動きします。Chrome 登場以前は Firefox に Tab Mix Plus とか Greasemonkey などのアドオンを入れて使ってましたが Quantum ではそれらのアドオンが非推奨になってしまっているようです。

今年はメジャーブラウザが全て WebAssembly をサポートしました。

blog.mozilla.org

C/C++ や Rust などネイティブコード生成言語の活用が見込まれる中、JVM 出身の Kotlin も (Kotlin/Native で) WebAssembly をサポートしています。

blog.jetbrains.com

来年は WebAssembly の事例が増えていくことでしょう。Web ブラウザがクロスプラットフォームなネイティブコード実行基盤になると、PWA とは別の世界が具現化するかもしれません。

Ingress

5周年記念メダル配信前に Level 15 になっていたので、Sage メダルでプラチナを獲得して Level 16 の条件が揃いました(AP 獲得はまだはるかに先ですが )。

charingress.tokyo

あまり情報収拾もせずにやっていたので、Agent Stats も知りませんでした。

f:id:kondoumh:20171223133702p:plain:w300

来年は Ingress Prime が登場するようですが Nexus 6P だとスペック的に厳しいかも。

app.famitsu.com

Google Play Music

Amazon Prime で使える Amazon Music でいいやと思ってやめてたんですが、やはり楽曲が限られてるので Google Play Music に回帰しました。契約してた頃のデータも残ってました。Amazon Echo なら Amazon Music Unlimited、iOS なら Apple Music とメインのデバイスに合わせて、ストリーミングサービスを切り替えるのがいいのかな。

旅かえる

ねこあつめに続く餌やり放置ゲー。写真すらもかえるが自分で撮ってきてくれるなど、やることが減ってガチャ要素が増しています。 www.hit-point.co.jp

Podcast

長距離通勤のお供に欠かせない存在です。

  • Rebuild.fm: 配信ペース落ちましたがレギュラー陣回が増えてる印象です。hak さん回が大好きです。
  • Backspace.fm: YouTuber になった drikin さんの VLOG と共に。最近ガジェットというよりプロ用機材を扱うことが多く、ついていけてません。
  • バイリンガルニュース: メジャー Podcast。今年の初め頃から聴いてます。いろんな学術的研究や実験のアブストラクトを紹介してくれるところが興味深い。
  • dex.fm:Android Developer の Podcast。30分目安で構成されててサクッと聴けます。
  • mozaic.fm: 更新再開されました。Monthly Web を定期的に、時々ゲスト回ということで安定配信が期待できます。
  • RADIOTAROSITE: 松村太郎さんが Apple 製品のことをひたすらモノローグで喋っています。有料マガジンアップルノートと連動。
  • Takram:プロダクトデザイン会社の社員さんが配信してます。意識高い感じですが、UX とかデザインシンキングとか機械学習の話題が聴けます。

更新頻度の低いのもいくつか購読。あとは ChangeLog や Software Engineering Radio で興味ある話題のエピソードをつまみ食い的に聴いてます。

終わりに

去年のふりかえりで個人開発や社内アプリ開発をやると決意してましたが成果はゼロ。仕事でも実装してないし・・朽ち果てないように錆び落とししていきたいと思います。

iPad でコードを書く Late 2017

久々に iPad で少しコードを書いてました。

1年前 Textastic + Prompt 2 や Coda for iOS で VPS 上に git clone したソースコードを sftp で読み書き、SSH で実行してました。この時は物理キーボード使わずソフトウェアキーボードで頑張ってました。iPad 用のキーボードはピッチ狭くて打ちにくいのと Air 2 の軽さが損なわれるからでした。

blog.kondoumh.com

去年買った Anker の TC930 はそこそこ打ちやすく、会議でのメモ取りに活用してます。

scrapbox.io

さらに今年「ひらくPCバッグ mini」買ったので iPad にキーボードカバーを追加する程度なら持ち運びが苦になりません。

blog.kondoumh.com

このバッグは膝の上に置くとちょっとしたデスクになり電車で座れた時タイピングしてもあまり傍迷惑じゃありません(たぶん)。座れなくても iPad 単体でソフトウェアキーボードを分割してタイピングできます。なので最近はキーボードカバーも持ち歩き、時々クラムシェルのように使ってます。

久々に Texstastic + Prompt でコードを修正・実行。Prompt はバックグラウンドに回るとすぐに接続切れちゃいますが、Split View で常にフォアグラウンドに居るので切れません。

f:id:kondoumh:20171222023317p:plain

iOS 11 でマルチタスクの使い勝手が向上したので Coda より快適です。SSH ならテザリングでも十分だしギガが減ることもないでしょう。物理キーボード使うと、当たり前ですが画面広く使えて入力も高速。

blog.kondoumh.com

www.textasticapp.com

panic.com

ターミナルとテキストエディタというストイックな環境も味わい深いですが、効率よく開発するには IDE を使いたいところです。何年も前から CodeanywhereOrionKoding など Web IDE を提供する PaaS はありましたが、 PC ブラウザじゃないと実用的なスピードで動きませんでした。ネットワークも Wi-Fi じゃないと厳しいし。しかし今の iPad は PC 並みにパワーアップしてブラウザのチューニングも進み、LTE の普及もあいまって環境は格段によくなっています。そこで Codenvy のクラウド開発環境を試しました。

codenvy.io

Java / .NET(core) / Node などの開発環境を Docker コンテナでデプロイして Eclipse Che のワークスペースでコード作成・デバッグできます。

f:id:kondoumh:20171223004407p:plain

流石に IDE だと画面の狭さが気になるのとタッチだと操作がツラいというのはありますが、想像以上にスムーズな動きです。コード補完もちゃんと動きます。A8 チップの Air 2 でもこの動きなので、いわんや Pro をやというところでしょうか。Cellular 版 iPad を使っている人なら検討の価値はあると思います。

iPad でモバイル開発環境を構築するとさらに魅力的なマシンになりますね。安くなった無印 iPad*1 でも構築できるので、荷物を軽くしたい or モバイル PC にあまりお金をかけたくないディベロッパーにはいいのではないでしょうか。

www.apple.com

*1:今年のモデルは iPad Air 2 より1世代進んだ A9 チップ搭載です

macOS 環境を最新化

Sierra は今年の初め頃導入してました。

blog.kondoumh.com

High Sierra はパスワードなしで root ログインできてしまうバグが出てたりしてたので、このまま年を越してもいいかなと思ってましたが、奥さんの MacBook Pro (Late 2012) がまだ OS X Yosemite で盛んに更新を促されるようになったので、見切りでアップデート。APFS への移行、アプリ設定の保持など特に問題なかったので、自分の MacBook Pro (Early 2015)も行くことに*1

事前に brew のパッケージは最新化してからインストールしました。

あっさりと完了*2

f:id:kondoumh:20171210112539p:plain

APFS にも引っ越し完了。

f:id:kondoumh:20171210112918p:plain

APFS の恩恵でストレージのステータス表示も心持ち速い?

f:id:kondoumh:20171210113049p:plain

普段使いのソフトウェアも問題なし。Sierra にアップデートできてるからか詰まる所もありませんでした。

開発ツールも最新化しておきます。

Xcode

f:id:kondoumh:20171210114841p:plain

IntelliJ IDEA

f:id:kondoumh:20171210114859p:plain

Visual Studio Community 2017 for Mac

f:id:kondoumh:20171210114916p:plain

最後に VMware Fusion で運用している Windows 10 です。VMware Fusion も起動するたびにアップグレードを促されてうざくなっていました。仮想マシンの Windows 10 は一足前に Fall Creators Update を適用済みです。

VMware Fusion を2年ぶりにアップグレードし Version 10 に。High Sierra と Windows 10 Fall Creators Update に対応済みと謳われています。

f:id:kondoumh:20171210113725p:plain

仮想マシンのマイグレーション、VMware tools の更新が行われ、最適化された模様です。

Visual Studio for Mac とともに、本家 Visual Studio も更新されています。

blogs.msdn.microsoft.com

こちらも更新しておきます。

f:id:kondoumh:20171210115609p:plain

ということで、年内に今年のソフトウェアアップデート作業を終えることが出来ました。

*1:普段は奥さんのマシンが2世代ぐらい前の OS になってるのですが、今回は先行して頂きました。にしても5年前のマシンですが、全く問題なく現役です。

*2:近年 OS の更新時でもデータのバックアップとか頑張って取らなくなってしまってます。

ストック情報サイトを Tumblr から Scrapbox に移行した話

Tumblr での運用

3年近く前、Tumblr にストック情報サイトを構築しました。

blog.kondoumh.com

stock.kondoumh.com

ブラウザで気軽に更新でき、ページの見栄えもそれなりで、タグ付けも簡単、API で可視化も可能…ということでわりと満足して使ってました。

しかし、記事の編集機能に関しては結構不満がありました。

Tumblr のエディタは OS 標準のキーバインドを乗っ取ってしまいます。macOS だと Emacs ライクなキーバインドが使えるはずなのに効かなくて書いてて突っかかります。

ダッシュボード(タイムライン)にモーダルでオーバーレイされるダイアログ内でのエディタのため、長文を書くのに向いていません。

Tumblr では Markdown が使えるのですが、画像挿入の GUI はリッチテキストモードでしか提供されておらず、Markdown モードで画像を挿入するには、最初にリッチテキストモードにしておいて画像をインラインでアップロードし、その後 Markdown モードに切り替えるとアップロードされた画像の URL が使えるというハックめいた操作が必要です。

元来 Tumblr は他サイトの画像や文章を引用してキャプションや出典など簡単な情報を付加してポストすることに特化したサービスです。したがってゼロから文書を作成するというユースケースのサポートは薄く、エディタや Markdown は二級市民扱いなのでした。

とはいえ、他に目的に合うサービスもなくて数年間使い続けてました。

Scrapbox への移行

Scrapbox は去年ぐらいから存在は知ってました。Dropbox の Paper と同様なモダンな Wiki かなという印象でした。最近 Scrapbox にブログを移行したりする人をちらほら見かけます。Scrapbox のプロジェクトの見た目は Tumblr のアーカイブ画面を思わせます。それで、ストック情報サイトを移行すればいいのではないかと思いつきました。

まずは、ガジェットに関する記事を Tumblr から Scrapbox に手動コピペで移行してみました。

WYSIWYG 編集可能

Scrapbox は閲覧モードと編集モードがシームレスな WYSIWYG 編集を可能にしており、Tumblr を始めとする一般的なブログツールの、編集 -> プレビューの繰り返しステップが不要です。画像やリンクなどの要素はインラインで編集状態になり、カーソルが移動すると閲覧モードになります*1。記事を読み返しながら気になったところをすぐに修正できるのがいいですね。他の人のページでもインライン編集モードで記法を確認できて参考になります。何しろ書くことの心理的障壁が低くなります。

同一タグの投稿がリアルタイムにリンクされる

記事内に #tagname を書くだけで、同一タグの既存の投稿がダイナミックにリンクとして出てきます。既存記事へのリンクも簡単に貼れます。 これも Scrapbox のキラー機能と言えるでしょう。

Emacs キーバインドを有効化できる

Edit Profile -> Extension で Emacs Key Binding を指定すれば、有効化されます*2。 プラグインで拡張できるため、拡張機能が充実してくればさらに快適な執筆環境が構築できそうです*3

画像の挿入が簡単

画像の挿入は、ファイルのドラッグ&ドロップでも、クリップボード経由でも簡単にできます*4。Gyazo サービスと連携しているようです。

gyazo.com

Markdown よりもシンプル
  • 箇条書きはインデントのみ
  • Table 書式もインデント + tab のみ*5*6
  • 見出しは * が多いほうが上位となり、既存の Wiki 記法の逆

独自マークアップも、これぐらいシンプルであれば、ヘルプを開く頻度が低くてちょうどいいです。

blog.kondoumh.com

Markdown には、URL のリンクはありますが、Wiki では普通のサイト内の他ページへのリンクはないため、Square branckets ([]) によるマークアップも妥当なところかと。

数式機能

今回、使ってないですが、TeX 記法で数式も扱えます。

増井先生からメンション頂きました。

API / 拡張

Scrapbox にも投稿タイトルや本文を取得する API が公開されていますが、タグを取得する API があるといいなと思います。

scrapbox.io

ブックマークレットなど色々な使いこなし Tips が纏められています。

scrapbox.io

プロジェクト単位の投稿管理

Scrapbox にはプロジェクトという単位で投稿を管理できます。ストック情報サイトでは、Gadget, Software, Portfolio というメジャータグを混在ポストしてました。Scrapbox ではテーマごとにプロジェクトを作った方が管理しやすく、ポータルも見やすくなりそうということで、個別にプロジェクト化することにしました。

scrapbox.io

プロジェクト内の投稿を一つ選んで Pin at home しておくと、プロジェクトのページ情報を oEmbed として取得してブログ等に埋め込み可能になります。

手動以外の移行方式

Scrapbox は JSON によるデータインポートが可能ですが、Tumblr はデータエクスポート機能がないので、今回は手動コピペしました。プロジェクトの Settings -> Page Data から Scrap to <プロジェクト名> という名前のブックマークレットが取得できます。これを使うと Web ページのリンクや選択範囲のテキストを引用として取り込むことができます*7

纏め

ということで Tumblr よりも書くことそのものが格段に快適で楽しい Scrapbox に移行しました。まだ全投稿を移したわけではありませんが元サイトの更新は止めて徐々に更新していこうと思います。

*1:他の人の投稿でも同じ動きをしますが、編集権限がなければ内容を上書きする心配はありません。

*2:Windows では C-n が 新規ページを開くコマンドに負けてしまいますが

*3:現状でも十分快適ですが。

*4:クリップボード経由の実装は画像の URL を使っているのか、イメージをそのままアップロードしているのかまでは調べていませんが。

*5:作った表は CSV ファイルとしてダウンロード可能です。

*6:Excel や既存の Wiki などからクリップボード経由で貼り付けても簡単に作表できます。

*7:現状では画像まで取り込むことはできないため、移行には適していません。