blog.syfm

徒然なるままに考えていることなどを書いていくブログ

重複したページを一括で閉じる Chrome 拡張機能をつくった

f:id:ktr_0731:20161228231158p:plain

動機

自分の場合、いろんなページを見ているといつの間にかタブを物凄く開いていることがあります。
それだけならいいけど、たまに同じページをいくつも開いている時もあって、ぐちゃぐちゃになることもしばしば。
タブが多くなるとタブのタイトルも埋もれていくから余計にそういう傾向になるのかもしれない…。
そこでいい感じに整理してくれる拡張機能があればいいなと思ってつくりました。

特徴

つくったもの↓

github.com

シンプルと言っていいのか手抜きと言っていいのかわからないですが、シンプルです。
メインのコードは19行しかないです。依存関係もないので package.json もないです。

タブやウインドウを管理するような拡張機能はいくつかありますし、自分も使用したことはあります。
ただ、別にいらない機能や、クリックする回数が多いものがほとんどで、結局面倒になって使わなくなりました。

自分が本当に欲しいのは、明らかに不要なタブを確認せずに閉じる機能だけなのです…。

excl はブラウザアクションボタン(ツールバーに表示されるボタン)をクリックされた時に、現在見ているページと同じ URL である他のページを自動ですべて閉じる機能のみを持ちます。
重複していれば勝手に閉じられますし、重複がなければ何も起きません。
あくまでパッとタブを見た時に、「あっ、同じタブ開いてそうだなー。」と思った時に押しておく程度の利用を想定しています。

GitHub のリリースページから excl.crx を右クリックとかで保存して、拡張機能の管理画面にドラッグ & ドロップすればインストールできると思います。

Chrome ウェブストアに公開しました。

chrome.google.com

まとめ

今まで作ったツールでも最も小さい実装かもしれない…。
今回は初めて Chrome拡張機能を開発したので、ドキュメントを読む時間のほうが明らかに長かったです。
それでも1時間くらいで作れました。
割りと拡張機能の開発は容易だったので、欲しい機能があれば今後もつくっていきたいです ✍️

Neovim のリモートプラグインを利用して好きな言語でプラグインを書く

この記事は Aizu Advent Calendar 2016 (Qiita) の 17日目の記事です。
前の人は @acomagu1 さんです。 次の人は @noah_orberg さんです。

f:id:ktr_0731:20161209001057p:plain

Neovim

突然ですが、Neovim はご存知でしょうか。
Vim は言わずもがな非常によく知られたテキストエディタの一つですが、Neovim はその Vim をフォークし、モダンアーキテクチャで再実装したテキストエディタです。

数十年前からの秘伝のタレは美味しいかもしれませんが、数十年前から続くソースコードが美味しいはずもなく、現在ではメンテナンスが大変なようです。
Neovim はメンテナンスの簡略化、効率化も図っており、自身の大きな特徴の一つとなっています。
ソースコードはもちろん OSS で公開されています。

github.com

新しいプラグイン/GUIアーキテクチャ

他の特徴としては Neovim のリモートプラグイン (rplugin) という、拡張性を高めるためのアーキテクチャがあります。

リモートプラグインと聞くとなんだか分かりにくいですが、プラグインを Neovim 本体とは別のプロセスで稼働させて、msgpack-RPC を利用して Neovim と相互にやりとりをしています。
msgpack-RPC でできることは以下の通りです。詳しくは 公式 Wiki を参照して下さい。

  • Vim コマンドの実行
  • Vim script の評価
  • バッファやウインドウ、タブの操作
  • Neovim 上のイベントの受け取り、ハンドリング

これを利用してGUI の部分を外部へ分離することで、Neovim コアのコードを軽量化し、メンテナブルにしているようです。
今回はリモートプラグインの開発について紹介しますが、UI のイベントを msgpack-RPC 経由で取得して、Neovim 自体を別のプラットフォームで動作させるようなアプリケーションなどもあります。
例えば Neovim の GUI を Web フロントエンド技術で実装した rhysd さんの NyaoVim が有名です。

github.com

実際には msgpack-RPC をラップしたクライアントライブラリを利用してプラグインを開発します。
つまり、msgpack-RPC を扱える言語であれば、原理上どんな言語でもプラグインを開発することができます。

コマンドラインで確認してみます。
まず、Neovim のみ (リモートプラグインを利用していない) 場合は、

f:id:ktr_0731:20161209002454p:plain

リモートプラグインを読み込んでいる場合は、

f:id:ktr_0731:20161209002720p:plain

このように、確かにリモートプラグインが Neovim 本体とは別のプロセスで動いていることがわかります。

クライアントライブラリ

Neovim 公式のクライアントライブラリは、Python、Node.js、Go、Lua の4つが用意されています。
コミット数やスターを見る限り、最も活発なのは Python クライアントのようです。

また、:help remote_plugin にも Python を用いたサンプルプラグインのコードが記載されています。
サードパーティ製のクライアントライブラリは、公式 Wiki で記載されているだけでも十分な数があります。

つくってみた 🚀

自分は Vimプラグインを開発したことはなかったのですが、Python で書けるならばできるかも…と感じ、実際につくってみました。
今回は、公式の python-client を利用しました。
Python で実装されたリモートプラグインの数は、現在最も多く、有名なものに Shougo さんの deoplete、denite などがあります。

とはいえ、ドキュメントは皆無に近いです。
ドキュメントを探すより、python-client のソースコードや他のプラグインの実装を見たりするのが一番手っ取り早いと思います。(割りと理解しやすいです🙌 )

つくったもの

Twitter クライアントを作りました。
Python3 を使っているので、Python3 で利用できるライブラリが使えるのがうれしいです。

github.com

そんなに時間を掛けていないので、最低限の機能しかないです…。
利用できる機能は、

  • ホーム、メンション、リストタイムラインの表示(非ストリーム)
  • ツイート
  • リツイート
  • いいね
  • リプライ

で、画面はこんな感じです。ストリームは上手くいかなくて保留中です。

f:id:ktr_0731:20161217143724p:plain

ディレクトリ構成

リモートプラグインディレクトリ構成は以下のようにする必要があります。
また、通常のプラグインと同様に $runtimepath/ 以下に配置するようにします。

.
└── rplugin
     └── python3
         └── tweet-nvim
             └── __init__.py

python-client での実装

python-client が Neovim とのインターフェースとなってくれているので、ほとんど意識する必要なくプラグインを書けます。
具体的には、クラスや各メソッドに Neovim のコマンドや関数として利用するためのデコレータを付与してあげる感じです。

詳しくはソースコードを見て欲しい(あまり整理してないので見て欲しくない)ですが、簡単に抜粋すると以下のような感じになります。

プラグイン定義

@neovim.plugin
class TweetNvim(object):

ツイート

    @neovim.command(_command_prefix + 'Tweet', nargs='+')
    def tweet(self, lines):
        content = '\n'.join(lines)

        if len(content) > TwitterAPI.MAX_CHARS:
            self.echo('Tweet must be less than {}'.format(TwitterAPI.MAX_CHARS))
            return

        TwitterAPI().tweet(content)
        self.echo('Tweeted')

感想

Vim script を知らなくても書けますが、流石に少しは Vim script を読めないと厳しいような感じでした。
とはいえ、Python を書けるならば、ほとんど学習コストはかかりませんでした。

ただ、一部の状態(window の id など)を python-client から取得できなかったので、まだあまり安定はしていないのかなとは感じます。
ちなみに冒頭でも言ったとおり、Vim script の評価はできるので、そこだけ Vim script で書くようにすれば取得自体はできます。

プラグインを自作する、と聞くとどうしても敷居が高そうに感じますが、意外とそうでもないので一度試してみてはどうでしょうか!

SECCON 2016 に参加した

初心者チームwabisabiとして、自分(id:ktr_0731)とid:ywkw1717id:kobadlve、ともう2人の計5人で参加した。 SECCON自体は去年も参加していて、チーム名は違うけどメンバーはほとんど同じだった。 チーム全体では4問解いた。 0点のチームを含めると1834チーム、含めないと930チーム中272位だった。 去年は575位だったので、半分くらいは順位が上がった感じ。 id:ywkw1717はBinary100のAnti-DebuggingとForensics100のMemory Analysis、id:kobadlveと自分はVoIP、はVigenereを解いていた。 個人的にWeb問を全く解けなかったので悔しい。本当に。 少なくともWeb300は十分解ける問題だった。 チームとしては成長しているけども自分自身は成長してない気がしたのでもっと頑張りたい。