Tips

IT技術系Tips

Sublime Text3でバイト数を表示するプラグイン作った

Codecs33をPackagesに入れないとダメ。
https://github.com/seanliang/Codecs33
あと、ConverToUTF8が入ってた方が嬉しい。

例のごとくOS X 10.9で動作確認。
winは知らない。

こんなイメージ
f:id:kaerouka:20140401235447p:plain

ソース→導入方法→雑記の流れで行きます。

ソース

import sublime, sublime_plugin
import codecs


class ByteLen(sublime_plugin.EventListener):

    def __init__(self):
        # statusに表示表辞書のkey
        self.status_key = 'bytes'
        # エンコーディングが取得できない場合に使用するエンコーディング
        self.default_encodings = ['cp932', 'utf-8']
        # エラー用
        unknown = '?'

    def on_selection_modified_async(self, view):
        text = ''
        for sel in view.sel():
            text += view.substr(sel)

        if not text:
            view.erase_status(self.status_key)
            return

        try:
            # origin_encodingは、ConvertToUTF8プラグインが指定している。
            n = len(codecs.encode(text, view.get_status('origin_encoding')))
        except:
            try:
                # 無理ならデフォルト
                for enc in self.default_encodings:
                    try:
                        n = len(codecs.encode(text, enc))
                    except:
                        pass
                    
                    # バイト数が取得できればelse句に進まずに正常終了
                    if n:
                        break
                else:
                    n = unknown
            except:
                n = unknown

        view.set_status(self.status_key, str(n) + ' bytes')

導入

ソースをbyte_len.pyという名前で、Sublime Text3の基本設定から辿れるPackagesフォルダにぶちこむだけ。
再起動位は必要かも。わかんない。
f:id:kaerouka:20140401235915p:plain
選択した箇所のバイト数が、左下のステータスバーに表示されるようになる。

雑記

なんでこんなプラグイン作ったかって、固定長のファイルを作りたかったからですよ。
レガシーなシステムとのやりとりって、未だに固定長だったりするわけで。
商品コード→38バイト目から30バイト
商品名→68バイト目から100バイト
みたいな仕様で渡ってくるデータが普通にあんの。

行の最後はCRLFで終わったりするんだけど、その前は必ず数字の2が入る!
とかそうゆう謎ルールがあったりする。

で、Sublimeさんは、選択した文字数はカウントしてくれても、バイト数はカウントしてくれない。
困るので作った。
秀丸サクラエディタだと、最初が0バイト目だったり1バイト目だったりして
何がなんだかわからんくなった記憶があったから、このプラグインは選択したバイト数の合計って形にした。

日本語周りでいろいろと足りなさすぎぜSublimeさん・・・

ソースのsublime開発周りを軽く解説

こんかいはsublime_plugin.EventListenerを継承して
on_selection_modified_async関数を実装することで、「何かを選択したらプラグインが動く」みたいなことしてる。
似たような関数でon_selection_modifiedってのがあるんだけど、こっちはまずい。
1文字ずつ連続して選択肢たりするとエラーメッセージと共に落ちる。
on_selection_modified_asyncは別スレッドで実行してくれるらしいので軽快に動作するみたい。
on_selection_modifiedの方は使い道がわからん。

左下のステータスバー関連の関数はこれら。

  1. set_status(key, value)
  2. get_status(key)
  3. erase_status(key)
  4. overwrite_status()
  5. set_overwrite_status(enabled)

ステータスバーに出てるエンコードするのに使った文字コードが欲しかったから
それを取ろうと思ったけど、keyがわからないから取れない。
こうゆうのマジ困る。
しかたないからConvertToUTF8のソース見てキー探してきたorz。

ちなみにencoding()の方はまともに動作しないから使ってない。
ConvertToUTF8使ってるからかしらんけど、いきなりWestern (Windows 1252)とか出てくる。
Sublime Text3の、ファイル→エンコードを指定して上書き保存の一覧に出てくるような文字列。