読者です 読者をやめる 読者になる 読者になる

よんちゅBlog

― このブログは自分用のメモや日々の問題などを共有するためのものです ―

20121005185841 お知らせ:  2013/07/17 ブログデザインをリニューアルしました。

accelerated-smooth-scroll という Vimプラグイン を作った (Vim Advent Calendar 2012, 167日目)

Vim Advent Calendar 2012 の167日目の記事です。

前回(166日目)の記事は @deris0126 さんの Vimでパターン検索するなら知っておいたほうがいいこと - derisの日記 でした。

先日Chrome拡張 Vimmers follow status を作ったのをきっかけに Vimmersページ に登録して頂いたので、これは VAC にも参加せねばと思い、参加させて頂きました。

今回は、GW中に作った Vimプラグイン accelerated-smooth-scroll のご紹介です。
(調べた限りでは類似のプラグインはなかったみたいですが、もしあったらごめんさない。)

accelerated-smooth-scrollとは?

名前の通り、smooth scroll に加速機能をつけた vimプライン です。

C-d/C-u による半ページ移動、C-f/C-b による1ページ移動の動作を置き換え、スムーズな画面移動を行いつつ、連続スクロール時には段々加速していくというものです。

長らく vim-scripts/Smooth-Scroll というプラグインを使用していたのですが、早くスクロールしたいときに邪魔になることがしばしばあったので作りました。

追記: 2013/05/17
動画が欲しいという天の声を聞いて用意してみました。
動画だとちょっとカクついていますが参考にどうぞ。

インストール方法

NeoBundle 使用時は以下で、

NeoBundle 'yonchu/accelerated-smooth-scroll'
使い方

デフォルトで <C-d>/<C-u> と <C-f>/<C-b> キーを置き換えるので、特に設定もなく使用出来ます。

マッピングを変更したい場合は以下のように設定します。

" デフォルトマッピングを無効にする (必要なら)
let g:ac_smooth_scroll_no_default_key_mappings = 1

nmap <silent> <C-d> <Plug>(ac-smooth-scroll-c-d)
nmap <silent> <C-u> <Plug>(ac-smooth-scroll-c-u)
nmap <silent> <C-f> <Plug>(ac-smooth-scroll-c-f)
nmap <silent> <C-b> <Plug>(ac-smooth-scroll-c-b)

加速機能のみオフにしたい場合は以下のように設定します。

let g:ac_smooth_scroll_enable_accelerating = 0

smooth scroll の初速を変更したい場合は以下のように設定します。

" <C-d>/<C-u> 時のスリープ時間 (msec) : 小さくするとスクロールが早くなります。
" Default : 10
let g:ac_smooth_scroll_du_sleep_time_msec = 5

" <C-f>/<C-b> 時のスリープ時間 (msec) : 小さくするとスクロールが早くなります。
" Default : 10
let g:ac_smooth_scroll_fb_sleep_time_msec = 5

加速度を変更したい場合は、以下の関数を定義して下さい。
以下の関数はスクロールキーを押す度に呼ばれます。

" 以下はデフォルトの定義です。

" スクロールスキップ数を求める
"   key_count : 連続でキーを押した回数
"   wlcount : 移動する行数 (1ページ移動の場合は1ページの行数, 半ページ移動の場合は半ページ分の行数)
function! g:ac_smooth_scroll_calc_step(key_count, wlcount)
  if a:key_count > a:wlcount / 2
    return a:wlcount
  endif
  return a:key_count
endfunction

" スリープ時間を求める
"   key_count : 連続でキーを押した回数
"   sleep_time_msec : スリープ時間の初期値
"     (g:ac_smooth_scroll_du_sleep_time_msec or g:ac_smooth_scroll_fb_sleep_time_msec の値)
function! g:ac_smooth_scroll_calc_sleep_time_msec(key_count, sleep_time_msec)
  return  a:sleep_time_msec - (a:key_count - 1)
endfunction

よかったら使ってみて下さい。
あと、バグなどありましたら教えてください。

以上、
Vim Advent Calendar 2012 167日目の記事、 accelerated-smooth-scroll の紹介でした。

次回 168日目は、 cohama(@c0hama) さんです。

Chrome拡張では、Background pages よりも Event pages を使用したほうが良い

これからChrome拡張を作る方には是非知っておいて欲しい機能、Event pages についての話です。

Event pages は、作成したChrome拡張によっては、必ずしも使用できるわけではありませんが、もし可能なら積極的に使用してほしいと思います。

公式ドキュメントでも、Background pages のページ冒頭には、以下の様な注意書きがなされています。

Caution: Consider using event pages instead. Learn more. via: Background Pages - Google Chrome

なぜ Event pages なのか

理由を詳しく説明すると、
Background pages を使用している拡張は、Chrome起動時にプロセスが起動され、以降Chromeが終了するまで生き続けます。
よって、例え Background pages が何もしていなくてもメモリその他のリソースを専有し続けることになります。

Chrome拡張が起動しているかどうかは、Chromeの Task Manager を見ることで簡単に確認することができます。
実際に見てもらえれば分かりますが、このメモリ消費が結構ばかになりません。

また、Background pages が起動しているかどうかは、Chrome拡張の一覧 (chrome://extensions/) で確認することができます。
(以下は英語表記ですが、日本語にしていれば日本語が表示されると思います。)

f:id:yonchu:20130509190710p:plain
f:id:yonchu:20130509190715p:plain

Chrome拡張 Vimmers follow status の場合

先日私が作ったChrome拡張 Vimmers follow status でも Background pages を使用していました。
(現在のバージョンでは Event pages 対応になっています)


この拡張は、一見すると Content script のみで実現できそうなのですが、Oauth認証を実装するためにどうしても Background pages を用意する必要がありました。
ですが、Oauth認証も常時使用しているわけではありません。
Vimmersページ にアクセスして "Show All!" ボタンをクリックしたときしか使用していません。
それ以外のときは、Background pages では何も行なっておらず、ただメモリだけが専有され続けていました。
ひどいですね。自分で作っといてなんですが、こんな拡張使えたものじゃありません。

そこで、Event pages の出番です。
Backgroud pages とほぼ同じ機能を持ちながら、必要な時だけ起動され、不要になると自動的に終了してくれるという、まさに今回のようなケースに適したものとなっています。

Chrome拡張 ニコ生アリーナ の場合

しかし冒頭でも述べたとおり、必ずしも Event pages が使えるわけではありません。

例えば、Vimmers follow status よりも前にリリースしたChorome拡張 ニコ生アリーナ では、Background pages 内で番組情報などのデータを持っており、バックグランドで定期的に新しい番組のチェックなどを行なっています。

定期的なチェックぐらいなら、alarms API を使用することでなんとかなりますが、番組情報をキャッシュとして持っていなければ、ポップアップを開くたびに取得しなければならず、非常に使いづらいものとなってしまいます。
(他にも極力無駄な通信が発生しないような工夫を施したりしています)

こういった拡張では Event pages を使用することは難しいでしょう。

Background pages を Event pages に移行する方法

では、実際にどうすれば Background pages を Event pages に変更できるか。
そのための指針は公式ドキュメントに示されています。


対象となるChrome拡張がどのような機能を有するかによって修正内容が違ってくるため、まずは Vimmers follow status で行った変更を説明していきます。
といっても大した変更ではありません。

手順1(共通): Manifest(manifest.json)の変更

Manifestを以下のように変更します。

{
  "name": "Vimmers follow status",
  "version": "0.1.0",
  "manifest_version" : 2,
  "description": "VimmersページにTwitterのフォロー状態を表示します。",
  "background" : {
    "page": "background.html"
  },
  // .... 以下省略
}

{
  "name": "Vimmers follow status",
  "version": "0.1.0",
  "manifest_version" : 2,
  "description": "VimmersページにTwitterのフォロー状態を表示します。",
  "background" : {
    "scripts": [
      "js/lib/chrome_ex_oauthsimple.js",
      "js/lib/chrome_ex_oauth.js",
      "js/eventPage.js",
      "js/lib/ga.js"
    ],
    "persistent": false
  },
  // .... 以下省略
}

この変更は Event pages 使用時に必須の変更です。

backgroud.html が不要になったので削除し、background.html 内で読み込んでいたjsファイルを全て scripts に書き出しています。
さらに、"persistent": false を設定することで、Background pages の非永続化を行い、Event pages 方式に変更しています。

手順2: chrome.extension.sendRequest -> chrome.runtime.sendMessage

これは私が知らなかっただけなのですが、
chrome.extension.sendRequest が Chrome ver.20 から deprecated となっていました。
それでも通常の Background pages では使用できていたんですが、Event pages では使用できなくなっていました。

誤って使用すると以下のようなエラーが出ます。

Uncaught Error: sendRequest and onRequest are obsolete. Please use sendMessage and onMessage instead.

親切ですね。おかげで気づけました。

また、Background pages でもいつ使用できなくなるか分かりませんので、使用している方は早めに移行した方が良いかと思います。


新方式の chrome.runtime.sendMessage については以下を参照下さい。


私が対応した限りでは、引数などは変わっていなかったため、リネームするだけで対応できました。

以上が、今回 Vimmers forllow status で修正した点になります。

これで、Vimmers follow status も無駄にメモリを専有しなくなり、経済的な拡張となりました。

以下に diff があるので良ければ参考にして下さい。

Background pages -> Event pages のまとめ

公式ページの Event pages へ移行するためのチェックリスト migrating existing background pages の日本語訳がどこにもないようでしたので意訳してみました。
参考にどうぞ。

background page から event page への変更

background page から event page 変更する場合は、以下のチェックリストに従って下さい。

  1. Manifest に "persistent": false を追加する。
  2. Event page 読み込み時に、毎回必要な受信eventを登録する。event page はChrome拡張をバージョンアップしたときにも一度だけ読み込まれ、登録したイベントの処理が行われる。
  3. Install時、またはUpgrade時のみ必要な初期化処理がある場合は、runtime.onInstalled をイベントを使用する。
  4. もし実行状態をメモリに保持しておく必要が有るなら、storage API または IndexdDB を使用する。event page は長時間ロードされていないため、実行状態を保持するのに global変数 は使用しないほうが良い。
  5. 必要なら、イベント通知を抑制するために event filters を使用する。例えば、tabs.onUpdated イベントを使用したい場合、代わりに filter 付きの webNavigation.onCompleted イベントを使用する (tabs API には filter がありません)。そうすることで、必要なイベントでのみ event page を読み込むことができる。
  6. runtime.onSuspend event を使用することで、event page 終了直前に処理を行うことができる。しかし、それよりも定期的な実行を推奨する。そうすることで、onSuspend イベントを受け取れずにChrome拡張がクラッシュした場合にも、データが失われません。
  7. window.setTimeout() または window.setInterval() の代わりに、alarms API を使用する。もし event page が途中でが終了してしまうような場合、このような DOM-based timers は使用出来ない。
  8. extension.getBackgroundPage の代わりに runtime.getBackgroundPage を使用する。このメソッドは、必要時に event page を起動するため、非同期で実行される。
  9. message passing を使用する場合、不要になった message ports は閉じなければならない。message ports が閉じられるまで、event page は終了することができません。
  10. context menu API を使用する場合、contextMenus.create に String型の id パラメータを設定(idは通常optional)する必要がある。また、onclick パラメータの代わりに contextMenus.onClicked を使用してlistener を登録する。

via: Event Pages - Google Chrome

誤りなどがありましたら、ご指摘頂ければと思います。

また、公式のサンプルアプリも非常に参考になるので、見ておくと良いかと思います。

以上、Event pages の説明でした。

VimmersページにTwitterのフォロー状態を表示するChrome拡張を作った

GWも終わり、新入社員の方々はそろそろ研修が終わって本格的に業務をこなしはじめる頃ではないでしょうか。
そして、今後どのエディタと付き合っていくかも、決めなければならない時期なのではないでしょうか。

まだ決まっていな方、そしてもう決めてしまった方も、今なら vim がおすすめですよ。

ところでみなさま、 vim-jp » Vimmers というページをご存知でしょうか?
このページでは、vimmer の中でも特に vim に詳しい方々や vim を愛してやまない方々が紹介されています。

これから vim をはじめようという方、まだはじめたばかりの方、
Vimmersページで紹介されている有名 vimmerTwitterでフォローしてみてはいかがでしょうか。
とても刺激になりますよ。


前置きが長くなりましたが、
今回はこの Vimmersページ をもっと活用していくために、Twitterのフォロー状態を表示するChrome拡張 Vimmers follow status を作ってみました。
(いったい何を作ってるんだと苦笑されそうですが…)

使い方

Vimmers follow status をインストール後、Vimmersページにアクセスし、"Show All!" ボタンをクリックすると、Twitterのフォロー状態が表示されるようになります。

f:id:yonchu:20130508205808p:plain

フォロー状態に応じて、Borderカラーが変わるようになっています。
また、フォローしている人数やフォローされている人数なども表示されます。

※ 初回アクセス時はTwitterアプリケーションの認証を行う必要があります。

ちなみに、私のフォロー状況はスクリーンショットの通りです。
うーん、まだまだですね。

みなさんもこれを期に、Vimmersページの方々をフォローして vim力 を高ためるきっかけを作ってみてはいかがでしょうか。
私もまだまだ未熟なので、もっともっと精進していきたいですね。
そしていつかは、このVimmersページに載せて頂けるような vimmer になりたいものです。

それと、私はVimmersページには載っていませんが、ついでに私のこともフォローして頂けたら、それはとってもうれしいなって。


追記 2013/05/08:
なんとVimmersページに追加されました。たった1時間たらずの ”いつか” でした…w
こういうこともあるので、みなさんもマサカリを恐れず積極的にアウトプットしていくと良いことがあるかも?

技術的な話も少し

開発期間は約1日で、
js は coffeescript で css は less で書きました。

Chrome拡張本体には coffeescript や less は含まれていませんが、以下にてソースコードを公開していますので、そちらを参照下さい。

実装は非常に簡単なものなので、はじめてChrome拡張を作るという方にも参考になるのではないでしょうか。

Browser Action と Options page はありませんが、Background と Content script を使用しているので、これらの連携方法や、Oauth認証の実装方法などが参考になるかと思います。

また、Chrome拡張をはじめて作る場合は、まずはドットインストールをやってみることをオススメします。
ひと通り見てみましたが、非常に分かりやすくてよかったです。

さらに詳しく知りたい場合は、公式ドキュメントを見ると良いでしょう。
内容も分かりやすく、量も実は思ったほど多くありません。
逆にネットの情報はChromeのバージョンやmanifestのバージョンが最新ではない場合が多いため気をつける必要があります。
困ったときはまず公式ドキュメントを見るほうが、変なつまづきがなくて良いかと思います。

以上。

バグ報告や要望、pull request などありましたらお気軽にどうぞ。


あと、まだアイコンがないので募集中です (^_^;)

追記: 2013/05/09
syui (PSP_T)さん にアイコンを作って頂きました。
ありがとうございます。

f:id:yonchu:20130509192249p:plain

まさか募集一日目で作って頂けるとは。

vimとtmuxのステータスラインを連携させてみた。

少し前からやってて意外と便利だったので紹介。
(しかし需要は極めて低いと思われる)

今回紹介する方法では tmux-powerline というtmuxのステータスラインをpowerline風にしてくれるスクリプトを使用します。

ただし、tmux-powerlineを使用しなくても、自身で必要な部分を作りこむことでも対応できます。

vim と tmux を連携してみる

まずは完成図を見て頂きましょう。

以下は通常時の tmux-powerline を使用したターミナル画面です。
tmuxのステータスラインに注目して下さい。
(表示情報が多すぎる気がするが、そこは気にしないでください。)

f:id:yonchu:20130322215933p:plain

続いて、vim を起動した時のターミナル画面です。

f:id:yonchu:20130322215514p:plain

いかがでしょう。
tmuxのステータスラインがガラリと変わったことに気づいたでしょうか。

vim起動後のステータスラインには、
vim内で選択されているバッファのディレクトリパスとそのディレクトリの git status が表示されています。

シェルのカレントディレクトリではありません。
vim 内でバッファを移動すれば、ステータスラインも更新されます。
また、vimを終了したり、tmux内で別ウィンドウや別ペインに移動した場合にも、それに応じて更新されます。

これでいつでも、ひと目でバッファのディレクトリとgitの状態が確認できます。

tmux-powerlineについて

tmux-powerlineの導入方法については、ここでは省かせて頂きます。
公式のreadmeを読むなりして導入して下さい。

ただ、tmux-powerline導入時に少しだけ注意があります。

tmux-powerline は2012年12月半ばあたりに大幅なバージョンアップが行われたため、過去の導入記事が役に立たなくなっています。
最新版の導入方法は公式readmeを見る必要があります。
(新verの tmux-powerline の導入方法について良い感じに説明しているページがあったのですが、失念してしまいました)

それと、tmux-powerline導入時に忘れがちな設定があります。
設定しなくも一部機能を除けば動作可能なのでですが、今回の話では必要なのでそこだけ書いておきます。
(公式readmeには書かれています)

bashの場合は .bashrc に以下の設定を、

PS1="$PS1"'$([ -n "$TMUX" ] && tmux setenv TMUXPWD_$(tmux display -p "#D" | tr -d %) "$PWD")'

zshの場合は .zshrc に以下の設定を追加して下さい。

PROMPT+='$([ -n "$TMUX" ] && tmux setenv TMUXPWD_$(tmux display -p "#D" | tr -d %) "$PWD")'

いずれもプロンプトに設定を追加していますが、プロンプトの表示内容には影響しませんのでご心配なく。

導入方法

遅くなりましたが、導入方法の説明をしていきましょう。

まず、.vimrc に以下の設定を記述します。

if exists('$TMUX')
  autocmd MyAutoCmd BufEnter * call <SID>set_vim_cwd_to_tmux()
  autocmd MyAutoCmd VimLeave * call <SID>del_vim_cwd_from_tmux()
endif

function! s:set_vim_cwd_to_tmux()
  if !exists('$TMUX')
    return
  endif

  let pain_id = system('tmux display -p "#D" | tr -d "%" | tr -d $"\n"')
  call system('tmux setenv ' . "TMUX_VIM_CWD_" . pain_id . ' ' . getcwd())

  let bt = &buftype
  let ft = &filetype
  " let bn = bufname('%')
  if bt ==# 'nofile' || ft ==# 'qf' || ft ==# 'quickrun'
    let pwd = getcwd()
  else
    let pwd = expand('%:p:h')
  endif

  let var_name = system('tmux display -p "TMUXPWD_#D" | tr -d "%" | tr -d $"\n"')
  call system('tmux setenv ' . var_name . ' ' . shellescape(pwd))
endfunction

function! s:del_vim_cwd_from_tmux()
  if !exists('$TMUX')
    return
  endif
  let var_name = system('tmux display -p "TMUX_VIM_CWD_#D" | tr -d "%" | tr -d $"\n"')
  call system('tmux setenv -u ' . var_name)
endfunction

簡単に説明すると、
バッファ移動(BufEnter)時に、tmux の環境変数 TMUX_VIM_CWD_#D に vim のカレントディレクトリ(cwd)のパスを設定し、TMUXPWD_#D に vim のバッファディレクトリのパスを設定しています。
さらに、vim終了(VimLeave)時には、TMUX_VIM_CWD_#D を削除しています。

TMUXPWD_#D は tmux-powerline が pwd を判定するのに使用している環境変数です。
この変数は削除する必要はありません。シェルのプロンプト更新時に自動的に更新されます。
TMUX_VIM_CWD_#D は今回新たに用意した環境変数です。

続いて、tmux-powerline のテーマ設定ファイルを変更します。
デフォルトのテーマを使用している場合は、tmux-powerline/themes/default.sh を変更して下さい。
自身で用意したものを使用している場合は、そちらを使用して下さい。

# Format: segment_name background_color foreground_color [non_default_separator]

vim_cwd=$(tmux showenv $(tmux display -p 'TMUX_VIM_CWD_#D' | tr -d '%') 2> /dev/null)
vim_cwd=${vim_cwd#*=}

if [ -n "$vim_cwd" ]; then
    # vim 起動時のステータスライン設定

    if [ -z $TMUX_POWERLINE_LEFT_STATUS_SEGMENTS ]; then
        TMUX_POWERLINE_LEFT_STATUS_SEGMENTS=(
            "tmux_session_info 148 234" \
            "hostname 63 255" \
            "vcs_branch 29 88" \
            "vcs_compare 60 255" \
            "vcs_staged 64 255" \
            "vcs_modified 9 255" \
            "vcs_others 245 0" \
        )
    fi

    if [ -z $TMUX_POWERLINE_RIGHT_STATUS_SEGMENTS ]; then
        TMUX_POWERLINE_RIGHT_STATUS_SEGMENTS=(
            "pwd 89 211" \
            #"vim-cwd 21 231" \
            "date_day 235 136" \
            "date 235 136 ${TMUX_POWERLINE_SEPARATOR_LEFT_THIN}" \
            "time 235 136 ${TMUX_POWERLINE_SEPARATOR_LEFT_THIN}" \
        )
    fi
else
    # vim未起動時のステータスライン設定
    # 以下は tmux-powerline デフォルトのテーマです。

    if [ -z $TMUX_POWERLINE_LEFT_STATUS_SEGMENTS ]; then
        TMUX_POWERLINE_LEFT_STATUS_SEGMENTS=(
            "tmux_session_info 148 234" \
            "hostname 33 0" \
            #"ifstat 30 255" \
            #"ifstat_sys 30 255" \
            "lan_ip 24 255 ${TMUX_POWERLINE_SEPARATOR_RIGHT_THIN}" \
            "wan_ip 24 255" \
            "vcs_branch 29 88" \
            "vcs_compare 60 255" \
            "vcs_staged 64 255" \
            "vcs_modified 9 255" \
            "vcs_others 245 0" \
        )
    fi

    if [ -z $TMUX_POWERLINE_RIGHT_STATUS_SEGMENTS ]; then
        TMUX_POWERLINE_RIGHT_STATUS_SEGMENTS=(
            #"earthquake 3 0" \
            "pwd 89 211" \
            "mailcount 9 255" \
            "now_playing 234 37" \
            #"cpu 240 136" \
            "load 237 167" \
            #"tmux_mem_cpu_load 234 136" \
            "battery 137 127" \
            "weather 37 255" \
            #"rainbarf 0 0" \
            #"xkb_layout 125 117" \
            "date_day 235 136" \
            "date 235 136 ${TMUX_POWERLINE_SEPARATOR_LEFT_THIN}" \
            "time 235 136 ${TMUX_POWERLINE_SEPARATOR_LEFT_THIN}" \
            #"utc_time 235 136 ${TMUX_POWERLINE_SEPARATOR_LEFT_THIN}" \
        )
    fi
fi

上記は一例ですので、ご自由に変更して下さい。

また、バッファのディレクトリではなくvimのカレントディレクトリを表示させたい場合は、下記スクリプトを segment ディレクトリに追加し、テーマ設定ファイルに vim-cwd を追加して下さい。

ちなみに私の設定は以下にありますので、参考にどうぞ。

以上です。

Chrome拡張 "ニコ生アリーナ" を作った。

春アニメの放送開始、GWのアニメ一挙など、来るべき戦いに敗北しないために作ったのが、今回のChrome拡張 "ニコ生アリーナ" です。

ニコニコ生放送を少しでも見ている方なら便利に使って頂けるのではないでしょうか。

主な機能は以下

  • ニコ生自動入場
  • ニコ生自動枠移動
  • 参加中のコミュニティ/チャンネルの放送番組の一覧表示
  • タイムシフト予約中の番組一覧表示
  • 公式放送番組の一覧表示
  • 一覧表示上に番組の状態(開場前/開場中/放送中)を表示
  • 番組の状態に応じた番組数をバッジ表示
  • デスクトップ通知
  • 自動タブオープン
  • ニコ生閲覧履歴


オススメの使い方

見たい番組をタイムシフト予約しておくと良いでしょう。

これでブラブザを開いてさえいれば、開場前に自動的にタブが開き、さらに開場と同時に自動的に入場してくれるようになります。

ユーザ生放送の場合は、コミュニティに入っておくと良いでしょう。
また自動的に次枠へ移動してくれるので、面倒な次枠チェックを行わなくてもすみます。

不具合報告など

不具合などありましたら、Chrome ウェブストア - ニコ生アリーナ の 詳細タブ の 「フィードバックを送信」から送って頂けるか、Twitter(@yuyuchu3333) などで教えて頂けると助かります。

お願いします。m(_ _)m

技術的な話も少し

開発期間は約1週間半、Chrome拡張を作ること自体ははじめてではりませんが、公開するのは今回がはじめてです。
ニコニコAPIが思ったより貧弱で時間がかかってしまった感じです。

Javascript は CoffeeScript で、CSSはLESSで書きました。
依存ライブラリは、今のところjQueryのみで、Bowerを使って導入しています。
ビルドツールには、Gruntを使用しています。

Chrome拡張本体には、CoffeeScriptやその他もろもろは含まれていませんので、コードを見たい方は以下を参照下さい。

不安要素が1つ。
実は今自宅にWindowsがないので、そこの動作確認がとれていません。
同じChromeだから大きな差はないと信じたい。(((( ;゚Д゚)))ガクガクブルブル
(しかも苦情がきても確認できないので直せない… pull requestとかくれると泣いて喜びます)

公開したばかりで、まだまだユーザ数は少ないですが、良ければ使ってみて下さい。

ブコメ返し

id:bowie2013 さん
報告ありがとうございます。
ver.0.2.3 にて修正しました。
まだ直っていないようでしたら、また教えてください。