Hatena::Diary

おつあり

2010-02-09

Sticky Shift

skk7.vimではなくてskk.vimです。

Sticky Shiftの需要が結構ある*1みたいなので、

skk7.vimのコードばっか書いてたのですがid:krogueさんのパッチだけ先に当てました。

あとパッチで追加されたグローバル変数をドキュメントに追記したり、

ついでにmap-plugブランチもmasterにマージしました。

これでarpeggio.vimとも連携ができます。

こんな風にfとj同時押しでIM起動とかできますよ!

let skk_control_j_key = ''  " skk.vimにマッピングさせないようにする
Arpeggio map! fj    <Plug>(skk-enable-im)

Sticky Shift楽ですねー。でもずっとシフトキー使ってたので慣れるまでちょっと時間かかるかも。



skk7.vimの名前の決め方

とうとうskk.vimの記事が投稿されて引けなくなりました。

vim-users.jpを読んでる人は多いと思うので名前候補も増えるかもしれません。

ということで名前の決め方だけ先に決めておきます。


名前の決め方

候補を募集した時と同じく

TwitterとかLingrとかで投票で決めたいと思います。

票は一人2票まで。

それか僕の目に付くところならどこでも構わないので、

このブログのどっかの記事のコメント欄ででも構いません。

名前候補は新しいskk.vimの名前案まとめ - おつありにまとめていくので、

そこから好きな名前候補を2つか1つ選んで、

Twitterなら#skk_vimのハッシュタグ付き*2か、Lingrのvim-users.jpでつぶやいてください。


投票受付期間

で、その票を受け付ける期間は、まぁ1週間ぐらいでしょうか。

一応名前の候補も1週間ほど受け付けます。


ようするに

今から2月16日の24:00までは名前の候補受付で、

2月17日の00:00から2月24日の24:00まで*3ということにします。


この間にskk7.vim実装できるかな...難しいかな...

*1Twitter / まさのり: @ShougoMatsu skk-sticky.el ... Twitter / Shougo.Matsu: @omasanori skk-sticky.elは便 ... Twitter / Shougo.Matsu: skkを使っているとリアルで小指が痛い……。これで長 ...

*2:そうでないと僕が気づけないので

*3:あってる?まぁあってなくてもそういうことにします。そろそろ名前決めなきゃgdgdすぎるので...

2010-02-01

skk.vimの構造について

まだ肝心のコードを書いていないので、

こういった構造は変わっていくと思いますが、

フィルタとモードのあたりは採用していきたいと思ってます。

skk.vimも多分こういう処理をしてると思うのですが、あまり追えてない...


このメモは開発中のものであるので、了承なく変更する可能性があるのでご了承ください。

このエントリが追記されなくなったら、 skk7.vimの仕様が固まったということです。

嘘みたいだろ・・・全部iPod touchで書いたんだぜ、これ・・・



この記事は僕のネタ帳みたいになってきてるので、現在の実装とは違っています。

現在の構造についてはいつかskk7.vimの構造が落ち着いてきたらエントリにします...

あとそういえば全部iPod touchはさすがに嘘でした。

いくつかPCでも書いてますが、もはやどの部分かは忘れました。



参考リンク



(2月1日)

ファイル

autoload/skk7.vim

いろいろ。

ここから始まる。

autoload/skk7/util.vim

色んなヘルパー関数。

autoload/skk7/event.vim

autocmd的なもの。

autoload/skk7/debug.vim

デバッグ時のみ読み込まれる。

autoload/skk7/compat.vim

skk.vimの設定をskk7.vim用にロードしたり、互換性のための関数など。

オプションで読み込まれる。

autoload/skk7/complete.vim

補完用。

Shougoさんに補完は書いてもらうつもりなのですが、

どういったAPIがいいんだろう。

補完のことよく分からない。

autoload/skk7/mode/*

モードについては後述。

autoload/skk7/test.vim

テスト用。TAP*1的なもの。

:call skk7#test#run()

だけでテストが走る。というのを目指すつもり。

これ別ライブラリにしちゃってもいいかな?と一瞬思ったけど

それがインストールされてなきゃテストできないのはうざいのでやめた。


イベント (autoload/skk7/event.vim)

  • 入力して字が表示される前
  • InsertChanged的な
    • それInsertChangedでできないの?
  • 変換する前
  • イベントで通知するより、モード固有でやれることはモードのautoload関数を呼ぶ形でやった方がいいかもしれない
  • ここは悩むところ

マッピング

  • 一文字打つごとにイベント投げたり処理を挟もうと思ったら自前でテーブル持ってないとダメじゃん keymap使えないじゃん
  • key"map"だからマッピングが完結するまでブロッキングされてしまう
  • lnoremap <expr> a lnoremap用関数('a')

フィルタ

  • 何らかのキーが押される度にフィルタを通して挿入される文字列を決めていく
  • フィルタ用関数の返り値は変換した文字列
    • lnoremap用関数でディスパッチされるためにlnoremap用関数が文字列を返せばいいのだけど、シンプルさのため
  • 変換キーが押されたらskkservなりgoogle suggestなり*2なんらかの関数に渡す
    • フィルタ関数の呼び出し元がめんどくさい変換部分の書き換えなどをやってくれる
    • 右側のみ更新されたら右側のみ(差分のみ)アップデートとか
    • 文字列検索でこういう後ろから検索していくアルゴリズムなかったっけ
  • 仮に大文字の英字やsticky keyなどを押すなどして変換中のことを「フィルタ待ち」と呼ぶ
    • フィルタ待ちかどうか確認する場合はskk7#...()で確認できる
  • それぞれの引数はorig_str, filtered_str, char, henkan_count, is_async
    • orig_str: フィルタ待ちの場合でない場合は"", フィルタ待ちの場合ここにバッファ文字列が入れられていく。この文字列はフィルタされた文字列ではなくてすべて英字である
    • filtered_str: 上と同じでバッファ文字列だが、フィルタがかけられた文字列が入れられていく
    • char: キー入力された文字列 ("o")
    • is_async: vimprocを使って非同期でフィルタ用関数が実行されているかどうか

モード
  • 各種フィルタ用関数を置くネームスペースと考える
  • あとフィルタ用関数は毎回呼び出される*3ので、毎回のフィルタごとに消えてなくならない変数*4、あるいはフィルタごとにやり取りするための変数なんかを決めておく
  • あとなんかフィルタ間でやり取りするための変数
    • そこら辺のことは次項の「ディスパッチ用関数/フィルタ用関数/での間のやり取りについて」で説明する
    • skk7#mode#...#filter_rom()
    • skk7#mode#...#filter_hira()
  • フィルタをかけて必要があれば他のステートに移る
  • autoload/skk.vim内で、ステートはs:skk7_state、モードs:skk7_modeとして表される
  • フィルタなどからモードやステートを見たり変更する場合は、操作用関数を通して操作する。
    • モードは変更できなくてもいい気がするけど、一応用意しておく
  • 例えばs:skk7_modeが"hira"、s:skk7_stateが"rom"であればskk7#mode#hira#filter_rom()が呼び出される
  • とは言え一から書くのはめんどくさい
  • _defaultというモードは使えなくなるけど、他のモードのためのヘルパー関数は次の通り
  • 引数などは変わるかもしれない
    • skk7#mode#_default#from_rom_to_hira(char, is_async)
      • ローマ字をうっていくとひらがなになる
      • charが大文字の英字だった場合やsticky keyだった場合は"▽"を返してskk7#mode#...#()などを呼び出してくれたり
    • skk7#mode#_default#from_rom_to_kanji()
      • ローマ字が入力されると同時に変換結果が表示されるAnthyの逐次変換のような動作をする
    • skk7#mode#_default#from_rom_to_kana()
      • qのカタカナモード用
    • skk7#mode#_default#from_kanji_to_hira()
      • 再変換用
    • skk7#mode#_default#from_hira_to_kanji()
      • モード固定で変換
  • 特定の範囲をフィルタにかけるoperatorなんてのもあればかなりいいよね
  • xxxからyyyに変換 みたいな
  • モードが存在しなかった場合は、存在すればskk7#mode#...#unknown_mode()、存在しないならskk7#mode#_default#unknown_mode()が呼び出される
  • ステートについても同じでunknown_state()が呼び出される
    • フック可能な訳は主にデバッグのため
    • あと「未実装です!!」とか言える
  • 入力したら別スレッドを起動するようにフィルタをかけて、入力をブロッキングしないようにしたい
  • 例えばid:mattnさんのgoogle-suggest.vimをskk7.vimで実現するなら、Googleへのリクエストを投げて、次のキー入力が来たら現在のリクエストをキャンセルしてまた新たにリクエストを投げる、など。普通だったらこれはGoogleからサジェスト結果が来るまで待っていなければならない。
    • vimprocがインストールされていればGoogleへのリクエストを別スレッドで行いたい
    • それだとDOS攻撃っぽくなるので、その他リクエストを投げるまでの時間(ms)などグローバル変数で指定できるといい
    • これはフィルタ関数内部で判断する
      • キー入力を受け付けた後に、skk7.vim側でフィルタ関数の呼び出しまで待っているのは意味がない
    • となるとそこらへんの同期処理をするautoload関数を書く必要が出てくる
    • 同期処理難しいのでこれもvimprocでできればうれしい
    • vimprocの辺りは非同期処理をした後のフィルタされた文字列の受け取りやそこら辺のイメージが曖昧なのでもっと考える

ディスパッチ用関数/フィルタ用関数での間のやり取りについて

  • フィルタ用の変数*5については、skk7#mode#...#の中に置いておけばいい?
    • まだニーズが分からないけど、モード間でやり取りしたい場合は変数をautoload化して公開すればできる

プラグイン

  • 全部autoload化してあるのでプラグインを作る時は楽?
    • 新しいモード
    • 新しいフィルタ用関数
      • 他のフィルタ用関数のヘルパー関数となるようなものを作りたい時はskk7#mode#_hoge#...()のように下線(_)をつけておく



(2月3日追記)


変換フェーズにおけるモード切り替えキーの扱い

  • skk.vimでは
    • 子音、つまりsなどの後にqが来た場合でも、sを消してモードを切り替えてしまう
    • 変換フェーズにおいては変換バッファ文字列を消すだけ
  • というかSKKというのはそういうもの
  • でも例えばqなどを、変換フェーズの時のみ変換のキーに割り当てられれば嬉しいんでしょう?
  • なにそれうれしい
  • 戸惑う人がいるだろうし、やるならオプションで
  • 詳しくは次項

特定の期間だけ有効なキー

  • マッピングを切り替えるのではなく、全てはディスパッチ関数で切り替える
  • skk.vimはここらへんモード切り替えキーのみ別々の関数だったりして流れが掴みにくかった

モードのキー割り当てについて

  • <と>と?にもまだなんか割り当てられそう
  • zはモードに割り当てた文字を入力したい時のエスケープみたいなものとして働く
    • もちろんキーはカスタマイズ可能
  • じゃあ@とかもz@で入力するようにすればモードに割り当てることはできるわけだ
  • でもそうやってどんどんモードを割り当てていくと、「z + 文字」が「文字」になることは個々のモードのテーブルに依存してるわけで、そうなると誰かが新しいモードを作ってくれた時とかは、そのキーを入力するために全てのモードのテーブルを書き換えなきゃならない
  • zをエスケープ文字列として、ディスパッチ関数側でz@は@にする
    • 全角の@を入力したい時は?
    • 現在のモードのテーブルにたずねて、なかったら半角の@にフォールバックする?
      • やっぱりテーブルの構造についても仕様化しないとダメだ
      • autoload/skk7/table/...

テーブルの構造の仕様

とりあえず現状では、YAML風に書くと

a:
  map_to:sa:
  map_to:xx:
  map_to:rest:x

テーブルを操作するコマンドマクロ

各テーブルの定義ファイル(autoload/skk7/table/*.vim)は下のような感じにすることを目標にする。

これは autoload/skk7/table/rom_to_hira.vim だとする。

またSkkTableMapにbangを付けると、例えばユーザ側で.vimrcで定義されていたとしても上書きする。

SkkTableMap -table=rom_to_hira          a   あ
SkkTableMap -table=rom_to_hira          sa  さ
SkkTableMap -table=rom_to_hira -rest=x  xx  っ

rom_to_hiraとテーブルを指定しているのはコマンドには呼び出されたファイルは分からないため。

どうせ同じテーブルの定義が一度に指定されるのだし、事前に知らせておくのはいいかもしれない。

SkkTable    rom_to_hira

SkkTableMap          a   あ
SkkTableMap          sa  さ
SkkTableMap -rest=x  xx  っ
迷っていること
  • 構文
  • これらのコマンドをローカルにするかグローバルにするか

ローカルにする場合は、テーブルの定義ファイルの先頭に次のようにする。

call skk7#table#define_macro()

ディスパッチ関数で(特別に?)処理すべきキー入力

まだ多分いろいろ追加・削除されてくと思う。

  • モードの切り替え (q Q l L /)
  • Sticky key
  • 大文字の英字
  • モード切り替えのためのキーのエスケープ用キー (z)
  • IMを有効にするキー (C-j)

ディスパッチ関数内の流れ

  • (上で挙げた)特殊なキーの処理
  • フィルタの処理
  • 補完の処理
  • 変換キーを押した時の処理は特に特別扱いしない
  • 変換キーがスペースキーだったとしたら、変換キーを押した時にスペースが挿入されるか文字列が更新されるかはフィルタ次第
    • 一応キーが変換キーかどうかを判断する関数を作る
    • 単純に変換キーがグローバル変換に保存されてるんだったらそれ見ればいいけど、マッピングの対応をグローバル変数にどのように保存するかは決めてないし
    • これもテーブルの構造と同じにする?
    • 変換キーは<Plug>なマッピングに割り当てておけばいいんじゃない?
    • 変換キーを押された回数はモードが持ってるべき
      • 必要があればその変数へアクセスするautoload関数なんかも
  • 変換を確定する関数作る

モードのコールバック

  • 特定のモードのみに送りたい場合はイベント発生よりもモードのautoload関数呼び出しのが効率や分かりやすさの点で優れている
    • 分かりやすさ、というのは主にモード側のイベント登録などの処理の話。コールバック呼び出しなら関数を定義しておくだけ
  • モードが変わった時
    • 変わる前のモードのコールバック呼び出し
      • 変わった後のモードを引数に渡す
    • 変わった後のモードのコールバック呼び出し
      • 変わる前のモードを引数に渡す
  • モード用のキーを押した時

イベント

  • あれ?要らない子じゃね?
  • 一番よく書けたと思ったコードだったのに...ギリギリ
  • モード以外にイベント的な処理するとこないしなぁ
  • まぁautoloadなので置いておいても損はないけど、使わなくなるかも

大文字の英字とSticky keyの扱い

  • Aは<Plug>(skk7-sticky-key)aと同じ

その他いろいろ

変換フェーズとそうでない場合にフィルタ用関数が返す文字列が、全部の文字列を返すのか一部の文字列を返すのか違う
  • フィルタ用関数は「確定した」文字列を返す
  • ディスパッチ関数が文字列の差分のみアップデートするなど工夫する
現在フィルタ側がバックスペースのキーコードを生成してるけど、これをディスパッチ関数にやらせる
  • 具体的には、フィルタ用関数は返り値(skk7#返り値を抽象化する関数を用意)として「削除する文字数」と「挿入する文字列」をディスパッチ関数に返すことが求められる
  • こうすることで、統一した文字列の更新が可能になる
  • Anthyでは、変換フェーズにたくさんの文字列を入力すると、いちいち全ての入力が書き換えられてるように見えて、それが結構遅かったのでイライラしてた

予測変換

一文節だけならできる




(2月4日追記)



マッピング

  • キーボード上の全てのキーはディスパッチ関数にマッピングされる
  • どのような動作をするかは独自のテーブルを持つ
    • マッピングを弄る専用関数作る
      • マッピングの引数などはarpeggioのマップ用関数を真似る
    • いずれコマンドマクロつくりたい


マッピングのコマンドマクロ

Skk7Map ; sticky
Skk7Map z escape
Skk7Map q zenei

これじゃ特殊なキーとモードの区別がつかない。

Skk7Map -type=sticky ;
Skk7Map -type=escape z
Skk7Map -type=mode q zenei

指定する引数はwordのみにすれば、次のように特殊なキーを保存することができる。

;: sticky
z: escape
q: mode-zenei
Skk7MapSticky ;
Skk7MapEscape z
Skk7MapMode q zenei

テーブル用にはSkk7TableMap。詳しくは前回の追記を参照。



テーブル用コマンド

  • ステートを持ってたり(前回ので言えばrom_to_hira)ややこしいので、テーブルの定義ファイル内の最後で削除するコマンドを実行する
  • いやステートを上書きすれば問題ないよ
  • ようするにテーブルの定義の前にちゃんと
Skk7Table table_name

とすれば問題ないという話

  • それともやっぱり明示的にテーブル名を指定させる?


フィルタ関数が返す値

まだ完全に実装のイメージがつかめてない。

多分補完関数についてよく知らないからだと思うので調べる。

  • 補完関数を見習う
    • つまり返り値は文字列か詳しく指定する辞書型か
  • 補完関数の返り値も含める?
  • 遅い場合も考えて、遅延できるようにする
    • 分けて処理することを伝えるキーと値を含める


メッセージキュー (autoload/skk7/msgqueue.vim)

  • ディスパッチ関数を非同期にする場合のみ読み込まれる
    • 有効ならdispatch_key()はそっちのがマッピングされる
      • マッピングする関数もautoloadにする
    • 実際の処理はskk7.vim側のdispatch_key()がする
    • やるのはspawnする処理
  • これ実現できたらfuzzyfinder.vimでも対応してほしい
    • キー入力を非同期に受け付けて、素早く入力した時の誤爆をなくしてほしいということ
  • いくつかの実装方法
    • vimproc
      • 不安定で現実的でない
      • こういう外部インターフェースに頼る方法は、Vim側が非同期に通知を受け取れないので、スクリプト側からvimproc側にポーリングしてやる必要がある
    • CursorHoldI
      • CursorHoldIでメッセージキューをデキューしていくイメージ?
    • いっそ外部コマンドでやったらどうなんだろうか・・・
    • +clientserver
      • id:mattnさんのpureirc.vimがいい例
      • Emacsってサーバとemacsclientっていう風に分けて起動できたような
        • あれは何が便利なんだろう
      • コマンドはSkk7Serverだとskkservっぽい
        • それでもいいような気がする
        • 片方のVimがサーバ的な役割は全て担う形
  • 処理のキューイングはどうする?
    • autoload/skk7/event.vim
      • 要らない子じゃなかった!


abbrevモードでスニペット機能を実現

  • 色んなスニペットプラグイン*6見る限り、専用の記法を導入してるみたい
  • 前回のメモの一時的なマッピングで、スニペットを挿入した直後だけ有効なマッピングも定義できる
  • xptみたいに<Tab>で次の引数の場所に移り、<CR>で関数のブロックの中に移るとかしたい
    • あれってどうやってスニペットファイルでそういうのを指定してたんだっけ
    • xpt自体は使ってるとVimが目に見えるほど遅くなるから使うのやめたけど...
    • コミット権もらったのにsvn分かんなくて結局一回もコミットしなかった...
    • そのうちコミットはなくなり...
    • そして誰もいなくなった
    • オーブンソースソフトウェアはニーズがあればふとしたことで生き返ることもあるんじゃないかな、skk.vimみたいに
  • これは「一時的なマッピング」と「特定の期間だけ有効なキー」で言ってるような感じで実装する


一時的なマッピング

  • フィルタ関数でマッピングテーブルいじるだけ・・・だとその前のマッピングが復元できなかったりする
  • 前回のマッピングだけ覚えていてくれればいい
  • 一時的なマッピングを作る専用関数を作る
    • 現在の値を保存してから値をセット
    • 一部あるいは全部復元
      • 復元する値がなかった場合はget()関数のようなデフォルトの値を指定させればそれを返す
      • 今の s:call_if_exists() と同じ
    • ちょうどやってること(値を復元する)は今の s:option_*() な関数と同じ
    • event.vimも s:option_*() な関数も、処理を指定した時に先延ばしさせるもの
    • 一緒にできないか


一緒にしてみた

  • まず処理の登録と同時にIDとなる値を返す
  • そのIDを保存しておき、指定したい時間にそのIDを渡して実行
  • event.vimを少し弄ればできるはず
  • 名前はqueue.vimのがいいかも
  • 似てると勘違いされないようにmsgqueue.vimもasync.vimとかにする?


一時的なマッピングについてもう少し

  • マッピングが変わってしまっても、ユーザに「これをすればリセットされる」みたいなコマンドを提供したい
  • ディスパッチテーブルをリセットする
    • コマンド
    • マッピング
      • IMが有効なら<C-j>でいいような
      • <C-j>をトグルするマッピング( <Plug>(skk7-toggle) )に割り当てたいユーザは?
      • <Plug>(skk7-reset-keys) みたいなマッピングを用意する
      • 初期化用のコードはそれに割り当てる関数に置いとけばいいかな?
      • じゃ <Plug>(skk7-init-keys) にするか


決め事

  • ブランチのフォーマットは<skkかskk7>/<タイプ>/<好きな名前>
  • タイプは機能修正なら頭にfix、機能追加ならhack、それ以外なら何もつけない


ステート

  • 活用の仕方が分からない
  • せめて特定の文字はこっちのフィルタ関数で処理、とかそういうことができればうれしいんじゃないか
    • skk7#register_filter_fn(mode, fn, chars)
    • これじゃフィルタ関数は登録しないと呼ばれないみたい
    • まぁデフォルトでfilter_main()以外は呼ばれないんだし合ってると言えば合ってるか
    • 引数を辞書型にして、例えばabcdefgをfilter_abcdefg()で処理したいんだったら
mode: hira
fn: abcdefg
handle: abcdefg

みたいなのを渡すとか?

キーのおかげで分かりやすそう

  • でも結局それmainからやればいいじゃん
    • 無駄にディスパッチの処理を増やすのはしたくない
  • 結論:ステート廃止?
  • いや待てモードの中で変数にステートを保存しておくよりは関数で分けられるのは地味に便利なんじゃないの?
    • いやだからそれmainからやればいいじゃん
    • うーーーーーん
  • 「入力中の処理の流れ/状態」の項の流れをディスパッチ関数で分けてくれるのはうれしい?
    • そうでもない
    • 例えば変換キーを押してひらがなから漢字に変換する場合はfilter_convert()でやりたいとする
    • その場合 filter_main() でそれが変換キーかどうか見て、それからステートをいじって、一回目は自分で

filter_convert() を呼び出す必要がある

    • だったら filter_main() でそのキーを見てからそれぞれのステート用の関数にディスパッチした方が分かりやすい
  • とりあえず先延ばしにしておくか


フィルタ用ディスパッチテーブル

  • 上で言ったようなステートの遷移をどのように表せばいいのか
state_a:
  b: state_b
state_b:
  a: state_a
  • モードなどは気が向いた誰かに追加していってほしい部分
  • なのでこういうステートの遷移などが便利なようならヘルパー関数書いとく


変換フェーズ

フェーズとかステートとかモードとか、一応使い分けるよう注意してるんですよ。

決してかっこつけたいとかそういう訳じゃないです。決して(ry

  • SKKには3つのフェーズがある
    • ノーマルフェーズ
    • 変換フェーズ
    • 送り仮名の変換フェーズ
  • とにかく変換フェーズか、そうでないか、では判断材料が足りない
  • それぞれのステートを定数で表す


入力中の処理の流れ/状態

これはフローチャートにした方が分かりやすいな。

いろいろ見落としてる気がする。

  • モードの中で行われるフェーズ
    • 英字からひらがな等に変換中
    • 変換後
  • sticky keyや英字を押して変換する文字列の入力フェーズ
  • もしもう一回sticky keyや大文字の英字キーを押した場合
    • 送り仮名入力待ちフェーズ
    • マッチしたので変換候補選択フェーズ
      • あれ?それともいきなり確定されるっけ?
  • 変換キーが押されて変換候補選択フェーズ


補完にもフェーズというかモードというかステートがある気がしてきた

  • というかなんか:helpにそう書いてある
  • autoload/skk7/complete/ に色んな補完関数を置く
  • その中のスクリプトは、モードと同じでコールバックやいくつかの関数を用意する必要がある
  • なかったら_default.vimにフォールバック?
  • モードと補完は一対一であるべきか
  • いや、googleでsuggestしたいじゃん
    • それは変換キーが押された時のモードのコールバックとして用意すればいいんじゃない?
  • 補完でもgoogle suggestありかも、DOS攻撃っぽくなるけどね


変換用API

  • autoload/skk7.vimに実装
  • フィルタは変換用のキーを自分自身でハンドルするべきか
  • 次の文字列をそれぞれ相互に変換
    • 英字
    • ひらがな
    • カタカナ
    • 漢字
  • n * (n - 1) 通りの変換関数を用意する必要がある?
  • いや文字の種類はそうそう変わらんだろ、アホか
  • 12個全部は実装無理っぽいかもしれない


ディスパッチ関数に渡す引数

  • どこから呼び出したか
  • キーは大文字か


その他

  • Vimana対応
  • vimup対応
  • コメントは日本語?英語?
  • funcをfunctionにする?
  • funcとfnの表記揺れ
  • mecab-skkserv使えば複数の文節で変換もできるよ!やったね!

最近全然眠れてない。




(2月5日追記)


だんだんとイメージがつかめてきた。

どうやらちょっと難しく考えすぎてたようで、

プラガブルにしようと意識するあまり

テーブルとモードの対応をどうするか、

補完とモードの対応をどうするか、

などいろんなことを考えていた。

それは全部モードがグローバル変数でやればいいことで、

それでもしほしいAPIなどが定まってきたら

後々しかるべき場所に実装してけばいいことだった。

文字列の更新や非同期な呼び出しなどはディスパッチ関数でやりたいけど、

それ以外は全部モードに丸投げしたっていい。

モードは他の人に書いてもらいたい部分だったから

あまりモードを複雑にしない方がいいんじゃないかと考えていたが、

それはまだ今考えるべきことではなかった。反省。



ディスパッチ関数の引数

  • 大文字かどうか
  • 現在の状態をキーとともに保存するか
    • Aの場合はAで保存しといて、aの時は保存しない


フィルタ関数

  • 変換キーが押された時は別のフィルタ関数を呼び出す
  • 現在のステートを廃止し、固定の名前でフィルタ関数を呼び出す


モードがcb_now_working()でtrueを返す場合の特殊なキーの挙動

  • フィルタ関数にそのまま渡す
  • 挙動がちょっと違うけど、各モードで使えるキーは最大限使わせる
  • qでカタカナに変換するのはhira.vimがやればいいよね


フィルタ関数に渡す引数

  • 現在のcolとline( getpos() ?)
  • 引数が多ければ...で省略すればいいじゃん
  • autoload関数で取得させるのは実質その変数はグローバルなのであんまりよくない


フィルタ関数の戻り値

  • 現在のバックスペースによる返り値も許容する
  • 長い文字列を置き換える場合
    • 返り値に挿入でなく置き換えであることを明示する値
    • replaceってキーに始点のgetpos()の結果を保存しとく


コールバック

  • skk7#sticky_key()から呼び出す
  • skk7#init_keys()から呼び出す


補完

  • 現状はとりあえず全部モードの中でやることにする
  • モード固有のグローバル変数とかあってもいいんじゃないかな
  • モードはEmacsでいうメジャーモードみたいな感じ?


モード

  • qなどのバッファ文字列を操作するキーはまとめておくといい
  • asciiモードはreturnするだけなので楽
  • モード起動のためのキーはもしマッピングされてなかったらマッピングする


マッピングテーブル

  • skk7/maptable.vimにわける?
    • s:special_keys以外に使えるようにするならオブジェクト指向風に書く
  • Vimのと同じ操作ができるといい
    • maparg()
    • mapcheck()
    • hasmapto()
      • マッピングにマップされたかどうかのフラグを持たせる


非同期

  • CursorMovedI
  • CursorHoldI
  • vimproc
  • +clientserver
    • 制限について調べる
  • Vimサーバ


グローバル変数

  • skk7_pre_load_files
    • 全てのautoloadファイルにload()って何もしない関数を持たせる




(2月6日追記)



keymap

  • 一文字が一文字と対応してるテーブルにはkeymapが使えるな
  • でも対応する意味あるの?
  • keymapの設定はめんどうというか慣れてない人が多い
    • keymapファイルを書くのは対応する文字を書けばいいから楽だけど
  • keymapの定義を切り替えられるだけでも便利
  • でもkeymapを読み込んだらマッピングを上書きされてしまう
    • Vimスクリプトをパースするのは死亡フラグ
  • リセットするキーとかはmapmode-icでマッピングする
    • メタキーと一緒のキーのみでいいような


補完はモード側でやるかディスパッチ関数側でやるか

  • これは実際Shougoさんにコードを見てもらって、どの時点で補完関数を呼び出せばいいのか訊く


変換候補

  • 候補は数字で選択できる
    • 数字を入力するときは?
  • prompt.vimがインストールされていれば、プロンプトでも選べる


変換用関数

  • 変換用関数もモード側にあればそっち使うべき?


ギャル文字変換テーブル

  • ・・・


「多く」「大く」

  • 「大ku」と辞書に書けないんだろうか
  • 動詞は活用の種類も保存できるといいんじゃ?
  • 活用の種類が保存されていたら送り仮名の母音の部分も見る
  • これSKKの辞書からYahooのAPIなりWeb上の辞書サービス使って変換できないかな
  • 辞書の形式はどうしよう
  • やっぱり変換や辞書の読み込みなどは別ファイルに分けるといいのかな
    • autoload/skk7/henkan.vim


独自マッピングテーブルはやめる

  • 引数でどこから起動したか判断すれば、独自のマッピングテーブル持つことないような
  • 補完関数のfindstartみたいな感じ
  • そもそもarpeggio使えないじゃん!



(2月7日追記)



変換フェーズ・変換バッファテーブル

  • 変換フェーズごとにバッファを持っている
  • (正確ではないけど)Sticky keyなどを押すたびに変換フェーズが変わる
  • バッファはテーブルで分けられてるので大文字で保存する必要はない
  • 変換する時は変換関数にテーブルごと渡せばいい
    • 変換関数はデフォルトでg:skk#henkan_buf_tableを使う
    • モードのがあればそっち使う
      • どんなケース?
  • 現在の変換フェーズの状態をstatuslineに表示できたらいいかも
  • 送り仮名は母音が入力されたら変換関数に渡す
  • 他にも変換キーが押されたら変換する
  • これらの処理はfilter_henkan()で行われる

#cb_ってプレフィックスいらなくね?

#フィルタ関数だってコールバックだし

  • ディスパッチ関数でバッファテーブルに入れていって、マッチしたらクリアの方がシンプルな気がする
  • それに再描画も簡単
  • 文字列の削除なども簡単
  • バッファテーブルを弄って、マッチしたらクリア
    • これっきゃない
  • フィルタ関数の返り値はどうする?
    • 関数で抽象化
      • throwしたっていい
    • 具体的には次のことが返り値か例外で知らせることができればいい
      • バッファテーブルの再描画する部分
      • 挿入する文字列
    • フィルタ関数実行中に変更されたバッファテーブルを監視していれば挿入する文字列だけでもいい
    • 返り値か例外って言ったけど、返り値は一切無視して関数で伝えてもいいんだよね
  • 辞書登録モードもバッファテーブルを用意して同じようにできたらいいな
  • 一応マーカーも設定できるように
  • それぞれのバッファテーブルは配列の辞書型にする
  • 文字列の他に位置も覚えておく必要がある
    • 前の追記でgetpos()とか言ってたやつ
    • フィルタされた文字列も含める


モードの再確認

  • 各モードは英字から何かへの変換、何かからまた違う何かへの変換をするもの
  • hiraモードだったら英字からひらがな、ひらがなから漢字
  • 最初の変換はシームレスに行われ、次の変換はSticky keyか大文字の英字を押すことで文字列を受け付ける
  • 2回目の変換の時に入力される文字列は最初の変換で入力される文字列と同じ
  • そこで変換キーが押されるか、新たにSticky keyか大文字の英字を押して送り仮名の母音を入力するとfilter_henkan() が呼ばれる
    • 現在はどの変換フェーズでもfilter_main()を呼び出してるけど、今後どうするか
    • もういっそfilter_main()はfilter()にして、変換キーが押されたらhenkan()を呼ぶのはどうか
    • 引数は同じ?
      • バッファテーブルを渡した方がいいんじゃないか
  • skk7.vimのバッファテーブルがグローバルなのはどうなんだろう
  • ローカルにして、それぞれゲッターとセッターを用意する
  • テーブルはモード固有のがあれば使う?
    • どういうケース?


モード固有のマッピング

  • 例えばhiraモードでqがカタカナへの変換になるとか
  • ユーザがいじれるとうれしい
  • 変わる前と変わった後にユーザが特定のコマンドを実行できればいいのか
    • モードに入ったらarpeggioでマッピングとか
    • モードを去る時にちゃんと後始末するコードも書く必要がある
    • それくらい単純な方がユーザにとっても分かりやすいような気がする


ユーザが登録できるイベント

  • フィルタが呼び出されるコールバックとは別
  • event.vim使い回す?
  • autocmd likeなコマンドマクロ
  • 投げるイベントはmode-モード名-enterとかにすればいいんじゃないか


モード側がやるべきこと

  • やっぱりplugin/の方で自分の名前を登録する
    • skk7#register_mode('hira')
    • その方がリスト表示してモードを決めたりできる
  • 補完
    • asciiモードなどは補完の必要がないため
    • 細かい制御などはモード固有のグローバル変数で
  • 使うテーブルの指定
    • グローバル変数


モードから呼び出す補完について

  • モードの補完関数はグローバル変数で決め、ローカルな値
  • CursorHoldIよりCursorMovedI的な挙動の方がうれしいらしい
  • 引数はVimのomnifuncで設定する関数と同じでいいんだろうか
  • neocomplcacheとの連携








変換フェーズ

  • ちゃんと名前があったみたい
  • ノーマルモードが■モード
  • 変換モードが▽モード
  • 送り仮名モードが▼モード
    • Qをひらがなの最初の位地で押せば▽モードに入れるらしい
    • ▽モードを抜けるてマーカーを消すには<C-j>
    • ▽モードを抜けてかつマーカーもマーカー以後の文字も消すには<C-g>


変換文字列などのシンタックスハイライト

  • それぞれの文字列にシンタックスハイライトができるといい
  • マーカーが設定されてれば楽そうだけど、マーカーが空文字の場合は動的にシンタックスグループを作る必要がある


q

「かなモード」、「カナモード」間をトグルする。

l

「かなモード」または「カナモード」から「アスキーモード」へ。

L

「かなモード」または「カナモード」から「全英モード」へ。

C-j

「アスキーモード」または「全英モード」から「かなモード」へ。

特殊なキーとして実装するんじゃなくて、モードのローカルなマッピングとして実装した方がいい気がする。

もちろんarpeggio対応!



辞書を編集

  • もちろんVimはエディタなので辞書編集にも最適な機能を発揮する




独自のマッピングテーブル

  • 要は<Plug>なマッピングにマッピングできればいいんだから、アプローチ自体はいいと思う
  • でもモードローカルなマッピングにする場合、autocmd的なものと合わせた方がいいのか、合わせるとしたらインターフェースはどういうものにしたらいいのか悩む。
  • というか今ここで悩んでる。


ドキュメント

  • skk7.vim
  • モードごと


SKKって中国語とかハングルとかも変換できないかな?

  • ノーマルフェーズで部首を表す漢字に変換
  • 変換フェーズではその部首を組み合わせた漢字にする
  • SKK最強じゃね?
    • さらに言うなら、skk7.vim最強じゃね?
    • 中国とか韓国でもSKK流行らせればよくね?
    • そして世界中に広まるSKKの輪
    • いや部首だけで何個あると思って(ry
    • 実際どういう入力方法なんだろうね?
  • ノーマルフェーズで細かい文字(ひらがな等)を入力、変換フェーズやその他のフェーズで複雑な文字に変換
  • 英字からの変換はテーブルを使って、それじゃ表現しきれない文字についてはどっかにリクエスト送ったりほげほげして複雑な文字にすると
    • 複雑な文字からより複雑な文字へ変換することも考えられるけど、そんな複雑な文字地球上に存在するの・・・?
    • 宇宙言語対応
  • 中国語のこととか考えてみると
    • ひらがなからカタカナへの変換なんかは別のテーブルに書く?
    • スペースを含んではいけないっていう現行のSKKのルールはない方がいい
      • 実装が複雑になるけど、今のskk7.vimらしく、現在のフェーズは自分で持っておく
      • 要するにマーカーに頼らない
      • skk7.vimではid:thincaさんがneocomplcacheでの併用で誤爆したってことからそういう実装にしたけど、これは良かったんじゃないか


skkserv

  • なんでHTTPみたいにGETとかPOSTとか分かりやすいリクエストじゃないんだろう・・・

*1http://blog.livedoor.jp/dankogai/archives/51024711.html http://en.wikipedia.org/wiki/Test_Anything_Protocol

*2id:mattnさんのgoogle-suggest.vimみたいに

*3:Win32 APIのウインドウプロシージャ的な

*4:static変数みたいに

*5:例えば変換中の文字列、送り仮名など

*6:xptemplate.vim, snippetsEmu.vim

2010-01-31

skk7.vim(仮称)

skk.vimの今後について。

skk.vimはコードが古くメンテナンスが難しいことから、

作り直した方がいいのではないかという声をちらほら*1見かけました。

なので、改めて新しく作り直すことにしました。

タイトルではskk7.vimとしていますが、あくまで仮称です。

名前については次のエントリでまとめます。


まだ手探りな状態ですが、keymap*2のおかげで簡単にひらがなを表示することができました。

後々のことを考えると、keymapでなく自前で「ローマ字→ひらがな」の処理をしたほうがいいのではないかと思いますが、 そこらへんは後から書き直せるように気を付けています。


また「ひらがな→漢字」の処理、つまり変換については、@ohacさんにskkserver*3というものを教えていただき、この処理もまたskkserverに丸投げできるのではないかと企んでいます。


リポジトリについて

現行のskk.vimのリポジトリに、ディレクトリを分けてskk7.vimを置くつもりです。

git-submoduleを使おうかと思っています。


現行のskk.vimについて

メンテナンスは続けるつもりです。

可能な限り続けたいのですが、冒頭でも言ったように

メンテナンス自体が難しいので、

skk7.vimではモダンPerlならぬモダンVimスクリプトというか、

とにかくそういったコードにしていきたい。

いつ新しいのが出来るか分からないけど、

なんだかんだ言ってしばらく現行バージョンにはお世話になると思う。


現行のskk.vimには素晴らしいパッチがたくさんある*4ので、

そういうパッチを拾う&作者をリポジトリに誘うという感じでやっていきたいところ。


Twitterでのログ

tyru(@tyru)/2010年01月30日 - Twilog

tyru(@tyru)/2010年01月31日 - Twilog



新しいskk.vimの名前案まとめ

@thinca @ShougoMatsu @krogue

メンバーのみなさんに質問です。

現在 #skk_vim の書き直し版を作っているのですが、

現在のskk7.vimという名前だと@thincaさんが

Vim8が出た時のことを考えていない、と仰ったので新しい名前を募集中です。

Twitter / tyru: @thinca @ShougoMatsu @krog ...

というわけで新しいskk.vimの名前募集中です。

今日だけですでにTwitterで主に俺とかid:thincaさんとか俺とか俺とか俺とか色んな人が案を出してくれました。

空気読まず混乱させるかのように一人大量に意見を出してる人がいましたが気にしないでください。

# Twitter開発とかアリなんじゃないだろうか。いやそれだったらIRCがあるか。しかしIRCいまいちよくわからない...

とりあえず今まで出てきたものを列挙してみる。


ネタ的なものも含まれてるのであまり気にせず

どんどん意見を出してくれたらいいと思います。


あとTwitterで#skk_vim付きでつぶやいてくれれば適時拾いますよ。

誰でも気軽にどうぞ。



つぶやき

いやほんと日本人で、仮名がある国に生まれて本当によかった。

skk.vimは仮名の力を最大限に使ってるIMと言えるような気がしてきた。

Twitter / tyru: いやほんと日本人で、仮名がある国に生まれて本当によか ...

中国のIMって確か一文字一文字部首から組み立てていくんじゃなかったっけ。

正直やってられないというか。

Twitter / tyru: 中国のIMって確か一文字一文字部首から組み立てていく ...

簡体字を繁体字に直すとか、

こういうニーズがあるんだなーとか見ながら考えると面白い

http://www.vim.org/scripts/script.php?script_id=999

Twitter / tyru: 簡体字を繁体字に直すとか、こういうニーズがあるんだな ...

*1http://twitter.com/mattn_jp/statuses/8372739597 http://twitter.com/krogue/status/8440108495

*2:help 'keymap'

*3:恥ずかしながら知りませんでした

*4id:krogueさんのパッチとか http://d.hatena.ne.jp/krogue/20081227/1230374715 他にもいろいろある

2010-01-30

skk.vimのmasterにいくつかpushしました

  • ドキュメント書いた
    • quickrunからコピペした!
  • タブをとりあえずスペースに置き換えた
    • :%s/^\t/\=repeat(' ', 8)/

とりあえずこれだけ。

あとrefactoringブランチで色々Challengingな変更を加えたいと思っているところ。


追記:

コピペしてチェックしたつもりが色々と間違ってたので修正。

「Fix typo」といいつつもあれがtypoと言える分量なのかは不明。

あとヘルプファイルって

タブが見えなくなったりしたり、

nomodifiableになったりと

かなり編集しづらいのですがみんなどうやって編集してるのか教えてください...


リファクタリングについては、やっぱりかなりの部分を書き換えなきゃならなくなりそう。

id:mattnさんなんかは「skk.vimはロジックだけパクって作り直した方がいいんじゃないかな」と仰っていたのですが、

やっぱりなんだかんだ言ってかなりの機能があるのできついです。

こういう時ささっと「とりあえず動く」バージョンを作れればカッコイイのですが。

無理なのかの判断もつきません。

lmapだとか色々Vimスクリプトでも知らない領域なのでどれぐらいかかるのか...


・・・あとmap-plugブランチなのですが、

コミットログの修正にうっかり--amendを使ってしまい、

その上Force Updateするという訳の分からないことをしてしまい、

Fast-Forwardでは更新できなくなってしまいました。

なのでmap-plugブランチをpullしたい方は

$ git pull -f origin map-plug

$ git branch -d map-plug    # 一旦削除
$ git pull origin map-plug

のようにしてください。すいませんorz もうしませんorz



MercurialからGit、あるいはGitからMercurialへリポジトリを変換する

GitからMercurial

これができれば見たいリポジトリはすべてGitで見られる。

GitはPerlのモジュールなんかあったり*1

結構Perlでサブコマンドとかが書きやすいので、

自分でいろいろ弄れる、かもしれない。

まだあんまり詳しくないけど。

hg から git へファストエクスポート

InterfacesFrontendsAndTools - Git SCM Wiki


MercurialからGit

正直あまり調べてないけど、

GitからMercurialの方法を調べてたらいろいろ見つかった。

Hg-Git Mercurial Plugin

「Warning, this software is still beta.」らしく、実用に足るものなのかは分からない。

ConvertExtension - Mercurial

いろんなVCSのリポジトリからMercurialのリポジトリへ変換。


欠点

書いてる途中気づいたけど、これらのツールは変換はしてくれるけどgit-svnみたいにpullはできない。

だからリポジトリで最新のブランチを追っかけるとかはできないけど、

なんか変換が必要な時はつかえるんじゃないかな、うん。

正直調べてちょっとがっくりきた。

いや上のwikiとかまだよく見てないんで調べればあるかもしれないけど。


あぁーgit-hgほしい。


ところで

hg から git へファストエクスポート

で知ったんだけど

InterfacesFrontendsAndTools - Git SCM Wiki

このページすごいね。

色んなVCSの相互的な連携機能というかツールがびっしりまとめられてる。

ドメインからして公式のwikiかな?

フィードないかなーと探してみるとあった

・・・けど最近更新されたものが出るんで、あんまり見やすくないな。

あ、Gitのフィードと言えばこれもおすすめ。


やり残したこと

しまった...この記事「とあるVCSの相互変換」にすればよかった... http://d.hatena.ne.jp/tyru/20100130/mercurial_and_git

Twitter / tyru: しまった...この記事「とあるVCSの相互変換」にす ...

f:id:tyru:20100130163819p:image



skk.vimのライセンスについて

とれてます。メールで確認して「お好きなように使っていただいて結構です」ということだったのでパブリックドメインだと判断しました。 #skk_vim RT @mattn_jp: githubのskk.vimってメンテナと連絡取れてるの?

Twitter / tyru: とれてます。メールで確認して「お好きなように使ってい ...

*1:まぁCPAN探せば大抵あるけど

2010-01-29

それVimperatorでできるよ

Google Chrome のテキストエリアを外部エディタで編集する Edit with Emacs - 酒日記 はてな支店

VimperatorからgVim呼び出し - おつあり

ようするにVimperatorで

set editor=エディタのパ<e3><82><b9>

としておけばエディタがテンポラリファイルを開いた状態で立ち上がって、

そのエディタが終了するとそのテンポラリファイルの内容がテキストボックスに反映されるという感じ。

追記:あれ、エディタのパスって書いたつもりが変になってる。



言語内言語

Perlは言語内言語が多すぎる。正規表現、(un)pack、(s)printf・・・どれも慣れてれば素晴らしく有用だから困る。 #perl

http://twitter.com/tyru/status/7477143057

そういやこれの他にglobもあるな。

しかもこれパスの区切りはMSWin32だとかUnixだとか関係なく/という罠。


ネタが尽きてくるとPerlの話をする辺り、もう末期なのかもしれない。

何の末期かは分からない。

2010-01-28

skk.vimのコミットルール

まずコミットルールなんかを決めた方がいいんじゃないかな、ということで。

そういうのあった方がやりやすいだろうし。


  • 基本的に機能の追加/バグの修正等したい場合にはトピックブランチを切ってプッシュ
  • そのパッチの妥当性の確認は必要?
    • やるとしたらTwitterとかIRCとかで確認するようにお願いできたら開発がスムーズに進むよね
    • skk.vimの開発については#skk_vim_devってハッシュタグでやりとりするとか?
    • IRCの場合はよく知らないので分からない

思いつくのはこれぐらいかなぁ。


wikiなんかがあれば、これらのルールに誰かが沿わなかった場合でも、一言こういうルールがあるよ、って言うだけで済むしね。

git初心者な人とかも気軽にパッチとか提供してくれたら助かるので、絶対ルールに従えって厳しくするつもりはない。

自由なのがgit/githubの良いところ!



FenrirFS

これ考え方がこれと似てるなぁ。

今あんまりWindows使わないので調べるのめんどくさいけど、ラベルを付ければ検索とかが楽にできそう。




コード概観


概観

インデント
  • スペース2個
  • &tabstop == 8
  • GNUスタイルって言うんだっけ?
  • 宗教論争にはあまり詳しくないのでよく分かりません

流れ

  • g:skk_control_j_keyを押す
    • マッピング(mapmode-l)のセットアップが行われる
  • mapmode-lになる*1

関数

SkkMode(on)

mapmode-lにする。

mapmode-lについては下の項目参照。


  • exists('b:skk_on') でなければs:SkkBufInit()が実行される
    • バッファ変数の初期化など
  • a:onがtrueの場合
    • s:SkkOn()
      • let b:skk_on = 1
    • SkkMap(silent)
      • a:silentはインサートモードの時はtrue、コマンドラインモードの時はfalse
    • s:SkkMapCR()
      • g:skk_egg_like_newlineなどを考慮して、<CR>の割り当てをする (TODO: これSkkMap(silent)の方に持っていってもいいかも)
    • 最後にSkkMode(on)は<C-r>=の中で評価されるので"\<C-^>"*2を返す
  • a:onがfalseの場合
    • (TODO: まだ見てない)
SkkMap(silent)

(TODO: まだよく見てない)

s:SkkKey(key)

キー入力ごとにこの関数が実行される。

特定のキー入力以外はs:SkkInsert(char)に渡す。

デバッグなどにはここにprintf()などを置いておくと分かりやすいかも。

function! s:SkkKey(key)
  echomsg printf('a:key = %s', a:key)
  echomsg printf('b:skk_on = %s, b:skk_mode = %s, b:skk_line = %s', b:skk_on, b:skk_mode, b:skk_line)
  echomsg printf('b:skk_rom = %s, b:skk_romv = %s, b:skk_rstart = %s', b:skk_rom, b:skk_romv, b:skk_rstart)
  echomsg printf('b:skk_henkan_mode = %s, b:skk_abbrev_mode_on = %s, b:skk_autofill = %s', b:skk_henkan_mode, b:skk_abbrev_mode_on, b:skk_autofill)
  sleep 1

  " ...

以下「変換」とタイプして変換するまでバッファ変数の変遷。

f:id:tyru:20100130133656p:image

s:SkkInsert(char)

コメントによると

入力の大元。ここで状態、キーを見てそれぞれの関数を呼び出す。

色んな関数を呼び出していて、まだよく見ていない。

ここら辺はキー入力してデバッグしながら流れを見ていくと分かりやすいかもしれない。


変数

バッファ変数

かなり多い。

s:SkkBufInit()とs:SkkSaveEnv()でいろいろ見られる。

s:skk_cmdline_*

なんだかよく分からない。

多分cmdline functionsで使われてるっぽくて、そこを見ると

「<C-r>= だと setcmdpos() が思ったように動かないため自前で組み立てる」

と書いてある。

バッドノウハウの香り

Vimのバグ・・・とか?

もしかしてここら辺ごっそりといらなくなるんじゃ・・・


mapmode-l

(TODO: まだよく(ry)

:help language-mapping にfとかrでlmapの設定が使えるって書いてあるんだけどこれマジか・・・

fとかrで日本語使えたら便利だなぁ。

skk.vimでこれサポートしたい。


気づいたこと

g:skk_control_j_keyを'<C-y>'にしているにも関わらず<C-j>でIMが終了する

コード見てて気づいたけど、<C-j>は特別なキーらしい。

s:SkkKey(key)で処理されてて、s:SkkControlJ()という関数を呼び出す。

この関数はここからしか呼ばれてなくて、

コメントに書かれてある通りSKKをonにすることはない。

elseif a:key == "\<C-j>"
  let str = s:SkkControlJ()

これは

elseif a:key == eval(printf('"\%s"', g:skk_control_j_key))
  let str = s:SkkControlJ()

こうするべきじゃないだろうか。

その他にも、キーがマッピングされてるのにも関わらずベタ書きされてるのはなんか理由があるんだろうか。


感想・その他

  • コードの整理とかやってもいいんだろうか。
  • あまりにも変えすぎるのはよくない。
    • 互換性は死守したい。(超重要)
    • あまり変わりすぎると他の人が手を加えにくくなってしまう。(これも重要)
    • でもそれをやるのは仕切ってる人(自分)の仕事だろうなぁとも思う。

できれば自分はこういう風に思ってるよーみたいな感想ください。

あとその必要性があるかどうかも知りたいです。


整理するとしたら
  • バッファ変数はできるだけ使わない
  • グローバル変数はできるだけs:つける

などなど。

*1:自分の環境だと「-- 挿入 (言語) --」と表示される

*2::help i_CTRL-^ か :help c_CTRL-^

2010-01-26

delicious/はてブから特定のリンクだけTumblr/Twitterに投稿

TwitterやTumblrにブクマを自動的に投稿する設定にしたものの多すぎてやめたんだけど、

特定のタグだけ投稿するようにすればいいじゃん、と思ってこんな感じにしてみた。

  • !share-with !twitter
    • Twitter用。
  • !share-with !tumblr-main
  • !share-with !tumblr-tech

なんで!share-with-twitterとかいう風にしないの?って言われたら、

のちのちdeliciousをインクリメンタルに検索できて、

かつGoogle風演算子を使えるアプリとか作ったとして、

「C++ -tag:!share-with」とかできるし。

「C++」は「any:C++」の略で全ての項目*1から検索、とか。


というかそんなアプリを誰か作ってください。

del.icio.us IncSearchとかいうFirefoxアドオンあるけど、いちいちブックマークを同期するのが面倒。

高速に検索できるようインデックスとか作る必要なければJSでもできそう。


追記:

!share-withタグを除いたら逆に有用な情報が消えそう。

あとTwitterはともかく、Tumblrはやっぱりtomblooとかのツール導入した方がいいかなぁ・・・

でもtomblooって複数tumblelog持ってた場合にもお構い無しに

メインのtumblelogに投稿しちゃうからなー。

tomblooに限らずTumblrの関連ツールは複数ブログを持ってる人のことを考えてなさすぎるorz



Regexp::Assembleのバグ?

追記:

バグだなんだ言ってねーで手動かせうんこ野郎。

ということで正規表現リテラル(?)じゃなく文字列で渡せばうまくいきました。

でも正規表現リテラルでもできなかったっけ?

コメント欄で紹介させてもらった弾さんの記事でも正規表現リテラル使ってるし。

自分でも前使った時うまく動いた気がするけど。

ただ今ネタ元のPerl HacksとPodのドキュメント見たらどっちも正規表現リテラルは使ってなかったので、やっぱ文字列を渡した方がいいらしい。



---



if, elsif, elsif, ... なコードをどう書き直せばわかりやすいか悩む修行 - 昨日知ったこと

の記事にコメントしたのでついでに同じことをRegexp::Assembleを使って書いてみたら正規表現エラーが出た。

次のコードって間違ってますか?

というか正規表現のエラーだからRegexp::Assembleが生成した正規表現が間違ってたとしか俺には思えないのですが。


エラーの内容は次の通り。

括弧の対応が足りないエラー。*2

Unmatched ) in regex; marked by <-- HERE in m/(?:(?msx-i:\A (\S+) \s* (?:(are) \s* (.+) \Z)(?{1})|(is) \s* (.+) \Z)(?{2}))|(?msx-i:\A (.*) \Z)(?{0})) <-- HERE / at /home/takuya/local/lib/perl5/Regexp/Assemble.pm line 996.

Podに

There is a mailing list for the discussion of "Regexp::Assemble". Subsc
ription details are available at <http://listes.mongueurs.net/mailman/l
istinfo/regexp-assemble>.

と書かれていたので明日あたり質問してみよう。

*1:タグ、本文、URL、ブコメ、等

*2:こんなミス機械的に生成してできるかな?