元記事:User-Quorn-SummerOfCode2008 - BlenderWiki


Python エディタの改良



by Quorn氏 



これは Text エディタに多数の新機能の追加と現機能の改良を行うことで、ユーザによる Python スクリプトの開発をもっと容易に行えるようにするプロジェクトです。

Blender への変更と現在の開発における対応方法についての情報は、Integration Document をお読み下さい。

新しいシステムの使用方法についての情報は User Manual をお読み下さい。
(訳注:両方とも未訳)


New Blender Text Editor Feature Demonstration from Ian Thompson on Vimeo.


Editor Features Part II from Ian Thompson on Vimeo.

現在の状況


このプロジェクトの鍵となるのは、Text プラグインシステムです。このシステムにより、ユーザや、ユーザが作業中のテキストと直接対話する Python スクリプトを作成できます。Text プラグインを書く方法については、後述の Text プラグインの記述の項をご覧下さい。

右のビデオはこのプロジェクトの機能紹介を行なう物です。完全なリストは後述します。



完成した機能


以下のリストは、このプロジェクトにより Blender にもたらされた機能の要約です。

[wiki]-コード/メンバの提示と補完(コンプリート)[[[完了]:http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15583]]
-ドキュメントをスクロールできるアクセスパネル [[[完了]:http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15635]]
-単語全体の操作 [[[完了]:http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15127]]
-挿入/上書きのサポート [[[完了]:http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15115]]
-アクティブファイル(もしくは "Internal")のヘッダリストと、変更済表示(*) [[[完了]:http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15148]]
-オプションによる外部からの変更チェックと報告 [[[完了]:http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15364]]
-ワードラップ

また、以下の問題を修正する予定です。
-ライブラリでリンクされたテキストが編集できるように。[[[修正]:http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15162]]
-ファイルの先頭で Backspace を行うと、Undo 時に空行が挿入されていました。[[[修正]:http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15119]][/wiki]


追加


以下は機能の追加と思われるもの、もしくはこのプロジェクトでのよい拡張と思われるものです。
[wiki]-すべてのテキストサーチ、Find と Replace の改良 [[[完了]:http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15721]]
-Blender のクリップボードとテキストのクリップボードとの連携 [[[完了]:https://projects.blender.org/tracker/index.php?func=detail&aid=17370&group_id=9&atid=127]]
-行と位置単位のマーカーと、これによってできることの追加 [[[完了]:http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15960]]
-コードのテンプレートと[[スニペット:http://live.gnome.org/Gedit/Plugins/Snippets]] [[[完了]:http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15982]]
-[[Mindrone氏の要望リスト:http://blender.mindrones.com/wishlist/text-editor]]
-他言語のサポートの向上
-スクリプト出力のリダイレクト[/wiki]


その他の既知の問題


[wiki]-後方に選択された文字列を再度削除する時の Redo が失敗していました。[[[修正]:http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15713]]
-先頭行で上、もしくは最終行で下を押すと、Undoが壊れます。[[[修正]:http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15789]][/wiki]


機能の解説




コード補完(Code Completion)


Python スクリプトを編集中、今のスクリプトで定義されている関数や変数のリストがあるといいなと思うことがよくあります。また、色んな関数や与えられたオブジェクトのフィールドをリスティングする機能があれば便利です。

このプロジェクトのコード補完セクションは、この両方をユーザにもたらし、更に別の補完方法(スニペットやタグなど)を実装するためのプラットフォームを提供します。

実際の補完はメソッドやフィールドの(あれば)少しの文字のみをタイプすると、サジェスチョンリストを呼び出すという形で行われます。
テンプレートのような補完なら、このシステムでは簡単に追加できるようになっています。ショートカットキー[Tab]でカーソルの前の単語を剥ぎ取り、いくつかのテンプレート辞書を見て、そのコード中の正しい位置へ setCursorPos() でカーソルを移動し、insert()でテンプレートを挿入するスクリプトを書くこともできます。もし時間があれば、そんな感じのスクリプトや作成チュートリアルをこのプロジェクトの終わりに公開したいと思います。

補完の呼び出しは、単に Syntax Highlighting(ヘッダの[AB]ボタン)と Python Text Plugins(となりのパイソンアイコン)を ON にし、[Ctrl]+[Space]を押すだけです。利用可能なすべてのモジュールや、利用可能もしくは定義済みの関数、変数がリストアップされます。更にスクリプトが import ステートメントで補完を行います。
import |
…そしてメンバフィールド
import Blender
Blender.|
|マークはカーソル位置です。最後にピリオドもしくはスペースを入力すると、コンテクストに応じたスクリプトを呼び出します。[Ctrl]+[Space]も使用可能です。


ドキュメントの列挙


コード補完と同じ行に、オブジェクトのドキュメントのクイックビューを表示可能です。これをインターフェイスに組み込むことにより、外部のドキュメントを使用する必要性を減らすことを目的としています。

現在、関数の内部で、
print somefunc(somevar, | )
[Ctrl]+[I]キーを押すと、somefunc 関数のドキュメントテキストがリストアップされます。もしカーソルが関数の括弧内になければ、その前の名前のドキュメントの文字列を表示しようとします。

import Blender|
この場合、"The main Blender module" の文字列を表示します。


編集方法


通常ユーザがエディタに当然あると思っている操作が Blender には多く欠けています。

テキストの上書きのサポート
このプロジェクト以前はテキストの挿入しかできず、[Ins]キーはほとんど使用されていませんでした。現在、[Ins]キーがトグルで挿入・上書きモードをトグルで変更し、カーソルもそれに合わせて変化します。

単語単位の操作
いくつかのエディタにある、[Ctrl]+[→]、[Ctrl]+[Del]、[Ctrl]+[BackSpace]などを追加しました。残念ながら、[Ctrl]+[←]/[→]はスクリーンの切り替えに使用されているため、同等の[Alt]キーを代替としています。

[wiki]-''[Alt]+[←]/[→]'':単語もしくは記号のグループ単位にカーソルを左右に移動
-''[Ctrl]もしくは[Alt]+[BackSpace]/[Del]'':カーソルの左右の単語を削除[/wiki]

ワードラップも欠けている機能のひとつで、スクリプト部分以外のテキストを書くのに非常に便利です。ワードラップは関連するトグルボタンを持つことになると思いますが、まだ未実装です。


Text プラグインの作成


Text プラグインを書くには、File → Script Templates → Text Plugin にあるテンプレートをご覧下さい。BPy モジュールには便利なツールを色々作成できる、新しい Text オブジェクト関数を集めてあります。

The BPyTextPlugin Module


多くの Text プラグインの中心のコンポーネントが、この Python モジュール、BPyTextPlugin です。このモジュールは構文解析と、Text オブジェクトに与えられた便利な情報を取得するためのツールを提供しています。ここではその動作とスクリプトを作成するためのインターフェイスを簡単に説明します。

最もよく使用されるメソッドが、get_cached_descriptor(txtobj)です。Blender Text オブジェクトを渡されると、ScriptDesc のインスタンスを返します。その Text があらかじめ構文解析されていなかった場合、もしくは理由はなんであれ、その Text を再度構文解析することが決定されると、parse_text(txtobj)が呼び出されます。このメソッドは強制的に再度構文解析するのにも使用されます。

import BPyTextPlugin, bpy

txt  = bpy.data.texts.active
desc = BPyTextPlugin.get_cached_descriptor(txt)

BPyTextPlugin.print_cache_for(txt)
ScriptDesc インスタンスを理解するのに一番いい方法は、BPyTextPlugin モジュール自身を見ることです。vars フィールドdefs フィールドは、そのテキストを更に説明する VarDesc インスタンスFuncDesc インスタンスのリストを提供します。classes フィールドは自身の vars と defs のリストを持つクラスへのアクセスを提供します。

それぞれのデスクリプタは、最初に定義された行の番号にアクセスするための
lineno フィールドと、そのシンボル名を取得するための name フィールドを持ちます。


Text オブジェクトへの変更


一旦スクリプトが必要とする情報を取得すれば、二つの新しいメソッドでこの情報をユーザに提供することができます。
[wiki]-''txt.showDoc(doc)'': ワードラップされたドキュメントを目立つパネルに簡単に表示できます。
-''txt.suggest(list, prefix)'': サジェスチョン(候補)リストの特定の接頭辞のアイテムのみを表示します。[/wiki]

また、下記を呼び出すことでマーカー(後述)を作成できます。
[wiki]-''txt.markSelection(group, (r,g,b), flags)'': 指定したグループ、色、挙動のフラグで現在の選択をマークします。flags に ''Text.TMARK_EDITALL'' を使用することで、同じグループのすべてのマーカーが同時に編集されるように指定できます。(注)[/wiki]
注:このフラグを持つマーカー群は、同じ長さの選択かつ同じ Text をマークしていなければなりません。

このサジェスチョンツールとドキュメントツールを使用したサンプルです。
import bpy
from BPyTextPlugin import suggest_cmp

txt = bpy.data.texts.active
sugs = [('suggest_me', 'v'),  # v for variable
        ('suggest_this', 'f') # f for function
       ]
sugs.sort(cmp=suggest_cmp)

txt.showDocs('Some kind of documentation string, automatically word-wrapped')
txt.suggest(sugs, 'suggest_')
注意:サジェスチョンリストをソートする必要はありませんが、できればした方がいいでしょう。ソートには sort(cmp=BPyTextPlugin.suggest_cmp) を使用して下さい。

Blender Text オブジェクト(txt)のその他の追加です。
[wiki]-''row, col = txt.getCursorPos()'': カーソル位置(行(row)、列(col))を返します。Python では通常行数は1からですが、ここでは row は0から始まることに注意して下さい。

-''txt.setCursorPos(row, col)'': Text オブジェクト内のカーソル位置を設定します(もしくは一番近くにします)。選択はクリアされます。

-''row, col = txt.getSelectPos()'': 選択のカーソル位置(row, col)を返します。Python では通常行数は1からですが、ここでは row は0から始まることに注意して下さい。

-''txt.setSelectPos(row, col)'': Text オブジェクト内の選択のカーソル位置を設定します(もしくは一番近くにします)。選択はこの位置まで延長されます。最初に選択の基点として ''setCursorPos'' を使用して下さい。

-''txt.insert(string)'': 現在のカーソル位置に ''string'' を挿入します。

-''txt.readline()'': 他の readline メソッドに従い、Text オブジェクトから一行読み出します。

-''txt.reset()'': IO ポインタを最初にリセットします(読み出し用) 。[/wiki]
これらのツールにより、クラスブラウザからテンプレート補完スクリプトまで、多くのプラグインを作成できます。


マーカー


マーカーはテキスト内をジャンプしたり、一度行ったところを繰り返し編集するのに便利なツールです。

これらは特定の箇所を埋めるテンプレートの作成や、find and replace オプションの拡張が可能です。
マーカーの動作については、前述の動画を観るか、下記の私のテンプレートスクリプトをご覧下さい。

https://svn.blender.org/svnroot/bf-blender/branches/soc-2008-quorn/release/scripts/textplugin_templates.py

このスクリプトで使用されているテンプレートの構文は、GEdit のスニペットを元にしています。


プロジェクトのスケジュール


最初の一週間、私は現在の実装とその可能性の概要についてできるだけ多くのことを学びべきです。いくつかの機能の単純化と修正もここで行われるでしょう。残りの時間については以下のように分けます。

Stage 1: コード補完、ドキュメンテーション、その他機能のバックエンド関数の実装。この段階では出力は通常コンソールに送られます。

Stage 2: 要求された情報を表示する UI の作成。出力はリクエスト時にこれらに送られます。

Stage 3: 高度な UI 機能とインタラクティブな機能(スクロール可能なドキュメンテーションパネルや、メンバ選択)の実装。また、ユーザがこれらの機能をON/OFFできるようにし、制限的ながら、できればオプションを UserPreferece に追加します。

Stage 4: シームレスな統合:コンテクストに応じた、特定のユーザリクエスト(例:ユーザが、. をタイプすると、その後に適切な変数を、もしくは[Tab]キーによるスニペット補完など)なしに起動するポップアップ。

Stage 5: 最終テスト、デバッグ、その他調整。できる限り最大のパフォーマンスを出すためのコードの最適化。

プロジェクトが完成すれば、Trunk にマージされた変更を一般の人たちにドキュメント化する予定です。この Wiki の Manual/Python_Scripting#The_Text_Editor のページも更新予定です。


私について


私は21歳の数学科の生徒で、ちょうど最後の年を終え、コンピュータアニメーションの修士課程に乗りだそうとしているところです。私は幼い頃からソフトウェアの開発を行っており、Pascal、Java、C、C++、Python などの多くの言語の経験があります。私はBlender3用のオープンソースのレンダーファームの開発中であり、日々の生活の中で多くのオープンソースツールを利用しています。

私は皆に役立つ何かを作るのが好きで、このプロジェクトがそうなることを願っています。


参考資料


GEdit Snippets
Mindrones' Wishlist
Distriblend


元記事:User-Quorn-SummerOfCode2008 - BlenderWiki
13:41, 16 August 2008版を元にしています