IMESupportがSublime Text 3に対応しました & Linuxでの日本語入力に関して

IMESupportがPackageControlに登録されました。

登録されたのは去年の11月末なんですが、書くのを忘れていました。現在はPackageControlからインストール可能です。
ただし、PackageControl自体が現時点ではSublime Text 3に対応していないため、Sublime Text 2のみです。

IMESupportがSublime Text 3に対応しました。

今までと同じリポジトリなので、git cloneするかzipでダウンロードしてインストールしてください。ST2/ST3の両対応となっています。
以下の点を含め、まだ動作がおかしい点があるかもしれません。

  • (ST3のみ)フォントの種別が適用されない。(フォント名の設定をまだ実装していないため)
  • (ST3のみ)特定の条件でインライン入力の位置がずれているような?(まだちゃんと確認していません)

ちなみに、ST3はプラグインが別プロセスで動作するようになったためプラグインのクラッシュの影響を受けなくなったそうですが、IMESupportはSetWindowsHookExを使ってsublime_text.exeのプロセスでプラグイン側のコードを動作させるようにしたため、IMESupportがクラッシュの要因になる可能性があります。
(別プロセスからIMEの制御が出来ないのでこうするしかありませんでした。)

Linuxでの日本語入力

現在のSublime Text 2は(InputHelperみたいなものを除いて)日本語入力できません。(Sublime Text 3は未確認です)
この状況を打破すべく、SublimeIBus の開発を開始しました。 これは ibus.el を Sublime Text 2 に移植したものです。まだまともに日本語入力できる状態ではないですが、LinuxSublime Textで日本語入力したいと思っている方は、ぜひ開発に協力してください。

Sublime Text Tips 3. 保存確認を出さないバッファを作成する

通常、 バッファを変更すると変更マークが付き、保存しないままそのバッファを閉じようとすると保存確認ダイアログが表示されます。これは、バッファをスクラッチバッファに設定すれば保存確認ダイアログを表示せずに閉じることができるようになります。
クラッチバッファに設定するには、対象のViewオブジェクトに対して set_scratch を呼び出します。

view.set_scratch(True)  # スクラッチバッファに設定する

クラッチバッファにするとバッファを編集しても変更マークが付かず、保存確認ダイアログも出ないため、プラグインが情報を表示するためにバッファを作成する際はスクラッチバッファに設定しておくとよいです。

Sublime Text Tips 2. コンソールで使用できる変数

Sublime Text 2はPython処理系を内蔵しており、シェルでpythonを起動したときのインタラクティブシェルのような、対話的な実行環境が利用できます。
コンソールを表示するには、メニューから View→Show Console を選択します。
コンソールではあらかじめ幾つかのモジュールがインポートされていたり、グローバル変数が設定されています。
使える物の一覧は、「globals().keys()」で表示できます。コンソールで入力してみると、以下のように表示されます。

>>> globals().keys()
['zipimport', '__builtins__', '__package__', 'sys', 'window', 'sublimelog', 'uzipimporter', 'LogWriter', '__name__', 'os', '__doc__', 'sublime', 'view']

つまり、あらかじめ以下のようにインポートされた状態になっています。

import zipimport
import os
import sys
import sublime
import sublimelog  # 詳細不明

また、viewとwindow変数が利用できます。viewは sublime.View クラス、 windowは sublime.Window クラスのインスタンスです。これらのクラスの詳細は API Reference - Sublime Text 2 Documentation を参照してください。
uzipimporterとLogWriterはよくわかりません。

viewとwindowには現在のビュー(タブ)とウィンドウに対応するインスタンスが設定されていて、ビューやウィンドウを切り替えると、この変数の内容も変わります。
特に重要なのはview変数です。Sublime Text 2のプラグイン作成では sublime.View クラスを使用して、カーソル位置を変更したり、テキスト内容を変更したりします。view変数が使えるため、実行しようとしているコード片をコンソールで気軽に実行することができます。
例えば、view.sel() は現在のカーソル位置、選択位置を返します。カーソルを移動してからコンソールに移って view.sel() を実行してみてください。カーソル位置により結果が変わってくることがわかると思います。カーソル位置は、簡単に言うとファイルの先頭からの文字数で表わされるんですが、詳細はまた別の記事で書こうと思います。

コンソールはSublime Text 2のプラグイン作成に大いに役立ちます。ぜひ活用してください。

Sublime Text Tips 1. sys.argvが存在しない

Sublime Text 2のPython処理系にはsys.argvが存在しません。実際にコンソールで「sys.argv」と入力してみると以下のエラーが表示されます。
(ちなみに、次の記事で説明する通り、コンソールではsysモジュールはインポート済みのため、 import sys を実行する必要はありません。)

>>> sys.argv
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'module' object has no attribute 'argv'

このことは、sys.argv を参照するモジュールで問題になります。たとえば、doctestモジュールはsys.argvを参照するため、そのまま使用するとエラーになってしまいます。
とりあえず、doctestを実行する前に、以下の通りにsys.argvに適当に設定しておけば、エラーは回避できます。

import sys
sys.argv = ["sublime_text.exe"]  # 適当に設定

これはあくまでSublime Text 2のPython処理系で実行したときの話です。doctestに限れば普通のテストはシェルから .py を叩いて実行したいはずなので、その場合は関係ありません。
ただし、普通のPython処理系では import sublime のようにしてSublime Text 2のモジュールを利用することはできないため、テストをSublime Text 2上で実行する必要があります。プラグインのテストをdoctestで書きたい場合は、上記の内容に気を付ける必要があります。

Sublime Text2は四畳半完全なエディタです

VimEmacsEclipseなど、現在のウインドウを横分割や縦分割していくものは

四畳半のようなウインドウの構成にすることができない問題。

http://d.hatena.ne.jp/tyru/20110108/matp

四畳半問題を解決できるウインドウ分割法のことを四畳半分割法という。今決めた。

そのような分割法を備えるウインドウマネージャを四畳半完全という。今決めた。

http://d.hatena.ne.jp/tyru/20110108/try_to_solve_matp

Sublime Text 2は四畳半のようなウインドウ分割が可能です。

このような分割にするには、.sublime-keymap で以下のように定義してキーバインドを実行します。

[
    {
        "keys": ["alt+shift+6"],
        "command": "set_layout",
        "args": {
            "cols": [0.0, 0.33, 0.66, 1.0],
            "rows": [0.0, 0.33, 0.66, 1.0],
            "cells": [
                [0, 0, 1, 2], // 1
                [1, 0, 3, 1], // 2
                [2, 1, 3, 3], // 3
                [0, 2, 2, 3], // 4
                [1, 1, 2, 2]  // 5
            ]
        }
    }
]

私もいまいち仕様がよくわかっていないので詳しい説明はしません。ただ、画像とキーバインド定義を見ればわかる通り、画像のウィンドウに表示されているAAの番号とキーバインド定義のコメントに書いてある番号が対応しています。

きっかけ

http://qiita.com/items/5ccbe63d36009680e0e6#comment-3e9349993ae4ccb1db78
IMESupportの不具合報告を受けたんですが、そのとき Sublime Text 2 で複雑なウィンドウ分割が可能なことを初めて知りました。
そしていつか読んだtyruさんの四畳半問題をすぐに思い出して、試してみたら出来てしまいました。

参考

http://www.sublimetext.com/forum/viewtopic.php?f=6&t=7284
set_layoutコマンドの説明が書いてあります。

VimGolfでハイスコアを取ったらトップの人のコメントが見れた話

この記事はこの問題の現在の最短手をバラしています。自分で解きたい人は見ないようにしてください。

この記事は Vim アドベントカレンダー 2012の20日目の記事です. 昨日は rhysd さんの 「立て!立つんだビムー!」 - はやくプログラムになりたい でした.

VimGolfは、テキスト編集をいかに少ないキーストロークで行えるか競うことができるwebサイトです。

トップの人のコメントが見れた

VimGolfは、ログインしている状態では自分の投稿した解法の手数と同じかそれより手数の多い解法を見ることができます。つまり、より少ない手数を達成すれば、上位の人の解法を見ることができるようになります。
また、投稿された解法に対してコメントを付けることができます。

私はこの問題を12手で投稿し、トップと同じスコアの2位(同率1位)を取りました。
投稿したのは2012/6/29なので、半年ほど前です。

この画像は私のアカウントでログインしてこの問題のページを開いてスクリーンショットを撮ったものです。前述の通り、私と同じ手数で投稿しないとこれを見ることはできません。
これを見ると、1番の Urtica dioica さんの投稿に Urtica dioica さん自身がこのようなコメントを残していることが確認できます。

Requires a terminal with 24 or more lines. In theory, there may be challenges where you could gain an advantage with a strange window size. In this case, you only miss out if you have an exceptionally small terminal.

Google翻訳したらこんな感じになりました。

24行以上の端末を必要とします。理論的には、変なウィンドウサイズでの優位性を得ることができる課題があるかもしれません。あなたは非常に小型の端末を持っている場合、このケースでは、あなただけ逃します。

Urtica dioica さんの投稿は24行未満の端末では結果が違ってしまうので、条件付きの解法であることが示されています。私自身は Urtica dioica さんと同じ解法(改行コードのみ異なる)で投稿しましたが、この条件には気付かずに投稿したので、このコメントを見て初めて気付きました。

こんな感じで、VimGolfにはコメントを残せるので、高いスコアを取ったら何かコメントを残しておくと後で同じスコアに辿りついた人が楽しめるかもしれません。

解法の説明

以降は同問題(Line Zipper)の解法の説明をします。
まず問題の概要ですが、以下のように離れたところにある同じ国名を隣り合わせの行に移動させるという問題です。
初期状態

China,1,2,3,4,5,6
Brazil,3,1,2,5,5,6
SAD,9,2,3,4,5,6
UK,3,8,3,9,5,1
France,7,2,3,4,5,6
Germany,1,7,3,2,5,6
Russia,1,6,2,9,5,6
Spain,1,2,2,4,5,6
Greece,1,3,3,4,5,6
India,4,2,3,4,5,6
Turkey,1,2,3,4,5,9
Poland,1,2,3,4,5,6
China,1,2,3,8,5,6
Brazil,1,2,3,4,5,6
SAD,1,2,3,4,5,6
UK,1,2,3,4,5,6
France,1,2,3,4,5,6
Germany,1,2,3,4,5,6
Russia,1,2,7,4,5,6
Spain,1,2,3,4,5,6
Greece,1,2,2,4,5,6
India,1,2,8,4,5,6
Turkey,1,2,1,7,5,6
Poland,2,2,3,9,5,6

終了状態

China,1,2,3,8,5,6
China,1,2,3,4,5,6
Brazil,1,2,3,4,5,6
Brazil,3,1,2,5,5,6
SAD,1,2,3,4,5,6
SAD,9,2,3,4,5,6
UK,1,2,3,4,5,6
UK,3,8,3,9,5,1
France,1,2,3,4,5,6
France,7,2,3,4,5,6
Germany,1,2,3,4,5,6
Germany,1,7,3,2,5,6
Russia,1,2,7,4,5,6
Russia,1,6,2,9,5,6
Spain,1,2,3,4,5,6
Spain,1,2,2,4,5,6
Greece,1,2,2,4,5,6
Greece,1,3,3,4,5,6
India,1,2,8,4,5,6
India,4,2,3,4,5,6
Turkey,1,2,1,7,5,6
Turkey,1,2,3,4,5,9
Poland,2,2,3,9,5,6
Poland,1,2,3,4,5,6

キーシーケンスは最初はMで始めます。

M:1m+11@:ZZ

Mはカーソルをスクリーンの中央の最初の非空白文字に移動します。これはカーソルを12行目に移動するのが目的です。それが達成できればM以外でもいいのですが、今回の問題ではたまたまMを使えば僅か1文字で12行目に移動できた、ということです。
そして、前述の通り、端末の高さがMの実行結果に影響し、12行目以外に移動すると失敗となります。

次に、":1m+"を実行します。

M:1m+11@:ZZ

すると、"China"の行が一気にくっつきます。

Brazil,3,1,2,5,5,6
SAD,9,2,3,4,5,6
UK,3,8,3,9,5,1
France,7,2,3,4,5,6
Germany,1,7,3,2,5,6
Russia,1,6,2,9,5,6
Spain,1,2,2,4,5,6
Greece,1,3,3,4,5,6
India,4,2,3,4,5,6
Turkey,1,2,3,4,5,9
Poland,1,2,3,4,5,6
China,1,2,3,8,5,6
China,1,2,3,4,5,6
Brazil,1,2,3,4,5,6
SAD,1,2,3,4,5,6
UK,1,2,3,4,5,6
France,1,2,3,4,5,6
Germany,1,2,3,4,5,6
Russia,1,2,7,4,5,6
Spain,1,2,3,4,5,6
Greece,1,2,2,4,5,6
India,1,2,8,4,5,6
Turkey,1,2,1,7,5,6
Poland,2,2,3,9,5,6

":1m+"は 行を移動するために :move コマンドを実行しています。:move の省略形が :m です。
:1move とすると1行目が移動対象になります。
:move+ とすると現在の行番号+1の次の行、つまりカーソル行の2行下の行が移動先となります。
組み合わせて ":1m+" とします。
現在行は12行目ですから、1行目を、14行目(移動前の14行目)に移動する動作となります。

次に、"@11:"を実行します。

M:1m+11@:ZZ

@: は直前に実行したExコマンドを1回繰り返すコマンドです。11@: とすれば11回繰り返します。

直前の ":1m+" を実行した後、カーソルは13行目にあります。ここで ":1m+"を繰り返すと今度は"Brazil"がくっつきます。

SAD,9,2,3,4,5,6
UK,3,8,3,9,5,1
France,7,2,3,4,5,6
Germany,1,7,3,2,5,6
Russia,1,6,2,9,5,6
Spain,1,2,2,4,5,6
Greece,1,3,3,4,5,6
India,4,2,3,4,5,6
Turkey,1,2,3,4,5,9
Poland,1,2,3,4,5,6
China,1,2,3,8,5,6
China,1,2,3,4,5,6
Brazil,1,2,3,4,5,6
Brazil,3,1,2,5,5,6
SAD,1,2,3,4,5,6
UK,1,2,3,4,5,6
France,1,2,3,4,5,6
Germany,1,2,3,4,5,6
Russia,1,2,7,4,5,6
Spain,1,2,3,4,5,6
Greece,1,2,2,4,5,6
India,1,2,8,4,5,6
Turkey,1,2,1,7,5,6
Poland,2,2,3,9,5,6

これ以降も単純に繰り返せば、次々と同じ国名の行がくっついていくことがわかるでしょう。これを 11@: として一気に処理すれば編集操作は完了です。

最後に、"ZZ"を実行します。

M:1m+11@:ZZ

ZZはファイルを保存してVimを終了します。これはVimGolfでは定石です。他にファイルを保存して終了する方法には :x があります。どちらも :wq と同等です。

説明は以上です。

おわりに

VimGolfは面白いのでぜひ皆さんもチャレンジしましょう。
明日のアドベントカレンダー担当は AmaiSaeta さんです.