| SciTE Lua スクリプト拡張 SciTE Lua Scripting Extension

### Lua スクリプト拡張覚え書き Lua Scripting Extension Notes

SciTE Lua スクリプト拡張は Lua 5.0.2 スクリプトエンジンの逐語的複製を使用しています。現時点ですべての標準ライブラリを含みますが、将来の版では一部を整理するかも知れません。

The SciTE Lua Scripting Extension uses a verbatim copy of Lua 5.0.2 as its scripting engine. Currently, all of the standard libraries are included, although this list may be trimmed in a future revision.

Lua is Copyright © 2003 TeCGraf, PUC-Rio. Lua の完全な利用許諾は SciTE をインストールしたディレクトリ内にある `luaCOPYRIGHT` に記されています。Lua の解説書を含むより詳しい情報は www.lua.org を参照ください。

Lua is Copyright (C) 2003 TeCGraf, PUC-Rio. The complete Lua license is included in `luaCOPYRIGHT` in the SciTE installation directory. To find more information about Lua, including documentation for the language itself, visit www.lua.org.

Lua に何ができるかについてはコミュニティポータル lua-users.org を調査することもできます。

For more ideas about what Lua can do, you may also want to check out the community portal, lua-users.org.

#### SciTE の属性と Lua イベント/コマンドハンドラ SciTE Properties and Lua Event / Command Handlers

`ext.lua.startup.script` と `extension.filepattern` の二つの属性で SciTE で用いるコマンドやイベントハンドラを定義できます。ext.lua で始まる他の属性も Lua の挙動に影響を与えることができます。詳細は SciTE 解説書をご覧ください。

The properties `ext.lua.startup.script` and `extension.filepattern` can be used to define commands and event handlers that will be called by the SciTE. Other properties beginning with ext.lua may also influence how Lua behaves. See the SciTE Documentation for more details on this.

起動時スクリプトやアクティブ拡張スクリプトで関数を定義することで、SciTE に希望通りの新しい挙動と機能を加え、深く結びつけることができます。

By defining functions in the startup script or the active extension script, you can tailor SciTE to your needs, adding new behavior and functionality that is tightly integrated.

はじめに、SciTE 拡張インタフェースによって外に出されている多くのイベントを操作することができます。イベントと同じ名前の関数を定義するだけでこれを実現できます。現在は`OnOpen`, `OnSwitchFile`, `OnSave`, `OnBeforeSave`, `OnChar`, `OnSavePointReached`, `OnSavePointLeft`, `OnDoubleClick`, `OnMarginClick`, `OnUserListSelection` に対応できます。

To begin, you can handle any many of the events exposed by the SciTE Extension Interface. You do this simply by defining functions with the same name as the event. Currently, `OnOpen`, `OnSwitchFile`, `OnSave`, `OnBeforeSave`, `OnChar`, `OnSavePointReached`, `OnSavePointLeft`, `OnDoubleClick`, `OnMarginClick`, and `OnUserListSelection` are supported.

これらのイベントの一部は SciTE がイベントハンドラに引数を渡します。`OnOpen`, `OnSwitchFile`, `OnSave`, `OnBeforeSave` へは最初の引数として影響を受けるバッファのファイル名が与えられます。`OnChar` ハンドラは一文字の文字列引数が来るでしょう。`OnUserListSelection` は二つの引数をうけとります。一覧の種別を示す番号と選択している項目の文字列です。ここに挙げなかったハンドラは引数を渡されません。

For some of these events, SciTE will pass one or more arguments to the event handler function: `OnOpen`, `OnSwitchFile`, `OnSave`, and `OnBeforeSave` will receive the filename of the affected buffer as their first argument. An `OnChar` handler should expect a single-character string argument. `OnUserListSelection` receives two arguments: a number indicating the list type, and a string indicating the selected item text. The other event handlers will not be passed any arguments.

イベントハンドラには SciTE がイベントの処理を続けるべきかどうかについて真偽値を返させます。イベントが満足に制御され、それ以上のハンドラを呼ぶ必要がないときに true(真)を返します。自分以外の拡張に同じイベントを処理させる機会を与える場合は false(偽)を返します。全てではありませんが、多くの場合イベントハンドラは偽を返すのがよいでしょう。Lua では「真ではない値」とは `false` と `nil` のみであることに注意してください。C++, Python, その他の多くと異なり、0 は `true` と評価されます。

Event handlers return a boolean value to indicate whether SciTE should continue processing the event. Return a true value to indicate that the event has been fully handled, and that no further handlers should be called. Return a false value to give other extensions a chance to process the same event. In many but not all cases, a well behaved event handler will return false. Remember that, in Lua, the only non-true values are `false` and `nil`. Unlike in C++, Python and many other languages, 0 evaluates to `true`.

もうひとつ `OnClear` という追加イベントハンドラがあります。拡張インタフェイスには明確に定義されていませんが、Lua には公開されています。バッファを切り替える、新しいファイルを開く、またはその他の理由で SciTE が特性ファイルを再読込するとき、Lua 拡張は最後に特性ファイルが読まれた後に作られた広域特性を削除し、上書きされていた方の値を復帰させます。起動時スクリプトが `OnClear` 関数を定義していた場合、その後でこの関数が呼び出され、(未訳）

There is one additional event handler, `OnClear`, that is not expressly defined in the Extension interface, but is exposed to Lua. Whenever SciTE re-reads the properties (which occurs every time you switch buffers or open a new file, but can also occur at other times), the Lua Extension removes any globals that were created since the last time properties were read, and restores any globals that were overwritten. Then, if the startup script defines a function `OnClear`, that function will be called so that scripts have a chance to clean up other changes they might have made outside of the Lua global scope (e.g. dynamic properties modified through the props object; see below) and/or to tailor the Lua environment according to local properties for the current buffer.

その後、SciTE は特性と拡張スクリプトを読み出します(未訳)。しかしながら、`OnClear` イベントが実行された時点ではまだ拡張スクリプトは読み出されていません。そのため `OnClear` は起動時スクリプトでのみ定義することができます。拡張スクリプトの中では定義できません。

After this, SciTE reads the properties and ultimately loads the extension script, if one is defined. However, at the time when the `OnClear` event fires, the extension script is not yet loaded. Thus, `OnClear` can only be defined in the startup script, not in an extension script.

イベントハンドラに加え、ツールメニューやキーボードショートカットで使える新しい関数を定義することもできます。Lua にコマンドを実行させるには subsystem に 3 を設定しておきます。その上で Lua を用いたコマンドを実装します。広域関数を定義してください。コマンド名が関数名となります。

In addition to event handlers, you can also use define new commands that are available through the Tools menu or through keyboard shortcuts. To specify that a command that will be handled by Lua, specify subsystem 3 for the command. Then, to implement the command using Lua, just define a global function. The command name is the function name.

ツールコマンドとして`dofile` や `dostring` といった定義済み関数を利用することができます。

You can also use predefined functions like `dofile` and `dostring` as tool commands.

コマンド名の後ろに与えられたものは単一の文字列引数として Lua 関数に渡されます。コマンドの例として、内部関数の dofile をもちいたものを次に示します。

Anything specified after the command name is passed to the Lua function as a single string argument. An example of a command, using the built-in dofile command, is shown below.

      command.name.1.*=Run My Script
      command.subsystem.1.*=3
      command.1.*=dofile $(SciteDefaultHome)/My Script.lua

コマンドラインは直接 Lua スクリプトとして評価されるわけではありません。

Note that the command line is "not" evaluated directly as a Lua script.

コマンド名に合致する関数がない場合でもエラーは表示されません。この場合はそのコマンドがSciTE Director 拡張のような他のものを意味すると Lua が仮定するからです。これに対し、コマンドが見つかった上で実行に失敗した場合はエラーが報告されます。

If there is no function matching the command name, no error will be displayed. This is because Lua assumes in this case that the command is meant for some other extension, such as the SciTE Director Extension. However, if the command function is found, but fails to execute, an error is reported.

#### 定義済みの Lua 関数およびオブジェクト Predefined Lua Functions and Objects:

Lua スクリプト内では、次の関数やオブジェクトが利用できます。

Within Lua scripts you can use the following functions / objects:

      trace(s) - 引数 s を出力部に書き込む。接頭辞や改行はない。
      dostring(s) - 引数 s をLua 4 の dostring のように Lua 文字列として実行する。
      editor - 編集部区画
      output - 出力部区画
      props - SciTE 属性を表す仮想表
      buffer - a table associated with the current buffer or document
      scite - a namespace for functions which control SciTE.

      trace(s) - writes s to the output pane (no prefix, no newlines)
      dostring(s) - executes s as a Lua string, like Lua 4's dostring
      editor - the editor pane
      output - the output pane
      props - a pseudo-table representing the SciTE properties
      buffer - a table associated with the current buffer or document
      scite - a namespace for functions which control SciTE.

これらに加え、Scintilla.iface に定義されている定数が Lua の広域変数として公開されます。関数名は SCI_ の接頭辞を付加された上でブロックキャピタル等価物として公開されます。

In addition, all constants defined in Scintilla.iface are exposed as Lua globals variables. Function names are exposed as their block capital equivalents, with the SCI_ prefix.

Lua 標準ライブラリで定義された関数とオブジェクトのすべてを利用できます。Lua 5 では dostring は廃止されましたが、ツールコマンドとしては便利という声があり、SciTE では復活しています。

All functions and objects defined in the Lua standard library are also available. Although dostring was deprecated in Lua 5, it is restored since some have said it would be useful in tool commands.

定義済み関数 `print()` の別名として`_ALERT()` 関数が定義されています。この関数は警告メッセージに改行を付してウィンドウに表示します。Lua からユーザにエラーメッセージを提供する便利な方法として利用できます。`_ALERT` はユーザが任意の別定義を行うことができます。

A function `_ALERT()` is also defined to be an alias for the built-in `print()`, which prints the alert message (plus a newline) to the window. This provides a reasonable way for Lua to present error messages to the user. You are free to override `_ALERT` with a different definition if you prefer.

props 仮想表を介して名前によって属性の読み書きができます。これは Lua における通常の表への操作と同じ方法、例えば props["property.name"] という形で参照できます。As with Lua tables, you can also un-set a property by assigning nil to its key.

The props pseudo-table allows you to read or write properties by name using normal Lua table-access semantics, e.g. `props["property.name"]`. As with Lua tables, you can also un-set a property by assigning nil to its key.

When you assign a value to a property from Lua, this overrides any values specified in the configuration files for that setting. The underlying file properties are not changed. If you later assign nil to the same property from Lua, this removes the run-time setting, allowing any file-based property setting to show through once again.

編集部と出力部の各区画には次の属性とメソッドが使用できます。

The editor and output panes support the following properties and methods:

      textrange(開始位置, 終了位置) - 指定区間の文字列を得る。

      findtext(文字列, [flags], [開始位置, [終了位置]])
        - 最初に合致した部分の開始位置及び終了位置を返す。合致部分がなければ nil を返す。
        - flags の省略値は 0 。指定できる値はSCFIND 定数に記されている値の組み合わせ。
          SCFIND_WHOLEWORD, SCFIND_MATCHCASE, SCFIND_REGEXP といった値。

      match(文字列, [flags], [開始位置])
        - 合致部を一巡する生成器を返す。例えば for m in editor:match(text, flags) do ... end の形で利用できる。
        - 合致オブジェクト(上の例における m )は読み出し専用の属性 pos, len, text を持っている。
          また replace(置換文字列) 関数を検索と置換のために用意している。
        - 合致部の巡回中に文書がその巡回によるもの以外で変更されたときは生成器は意味を失う。
        - また巡回のあとに利用することを意図して合致オブジェクトを保持しないでください。
          そのような使い方はできません。

      append(文字列) - 文字列を文書の終わりに追加。
      insert(位置, 文字列) - 指定位置に文字列を挿入。
      remove(開始位置, 終了位置) - 指定範囲を削除。

      textrange(startPos, endPos) - gets the text in the specified range

      findtext(text, [flags], [startPos, [endPos]])
        - returns the start and end of the first match, or nil if no match
        - flags can be 0 (the default), or a combination of SCFIND constants
          such as SCFIND_WHOLEWORD, SCFIND_MATCHCASE, and SCFIND_REGEXP

      match(text, [flags], [startPos])
        - returns a generator that allows you to loop over the matches
          i.e. for m in editor:match(text, flags) do ... end
        - the match object (i.e. the loop counter m in the above
          example) supports read-only properties pos, len, and text;
          and also supports a function replace(replaceText) to
          support search and replace.
        - while looping through matches, if the document is modified
          by any method other than the loop counter's replace method,
          this may cause the match generator to lose its place.
        - also, do not attempt to store the match object for later
          access outside the loop; it will not be useable.

      append(text) - appends text to the end of the document
      insert(pos, text) - inserts text at the specified position
      remove(startPos, endPos) - removes the text in the range

Scintilla.iface で定義された関数の大部分は区画のメソッドとしても公開されています。これらの関数は簡素な引数（文字列、真偽値、数値）を持ち、全機能が利用可能です。例えば `editor:InsertText(位置, 文字列)` は実際に `editor:insert(位置, 文字列)` と同じものです。stringresult を引数に持つ関数は戻り値に文字列を含めます。文字列と stringresult のいずれに対しても Lua からは長さを渡さないでください。長さは指定されるかわりに状況から推定されます。

Most of the functions defined in Scintilla.iface are also be exposed as pane methods. Those functions having simple parameters (string, boolean, and numeric types) are fully supported. For example, `editor:InsertText(pos, text)` does practically the same thing as `editor:insert(pos, text)`. Functions having a stringresult parameter will include a string in the return value. For both strings and stringresults, if the function is documented as expecting a length as its first parameter, you do not pass the length from Lua. Instead, it is inferred from the context.

keymod 引数型は部分的に対応しています。iface 関数が keymod を取るよう宣言されている場合は Lua は二つの数値が来るものと考えます。ひとつめはキーコード( `SCK_LEFT` や `string.byte("'")` など)、ふたつめは修飾キー( `SCMOD_CTRL` など)です。

The keymod parameter type has partial support. When an iface function is declared as taking a keymod, the Lua equivalent expects two numbers: first the key code (e.g. `SCK_LEFT` or `string.byte("'")`, and second the modifiers (e.g. `SCMOD_CTRL`).

それ以上の複雑な引数を取る関数は使用できません。

Functions that have more complex parameters are not supported.

結果を持つ数値型を返すよう宣言されている関数は自身の戻り値を追加した結果を持っています。stringresult も持っている関数ではそれが先に、続いて数値の戻り値が来ます。

Functions that are declared to return a numeric type have the result added to their return value. If the function also has a stringresult, that comes first, followed by the numeric return value.

関数のいくつかは 'fun' ではなく 'get' あるいは 'set' として iface ファイルで宣言されています。これらは一般的に Lua に属性として公開されています（例: `editor.TabSize = 8` ）。get や set を行うもののいくつかは引数を取ります。`editor.StyleBold[SCE_PROPS_DEFAULT] = true` のように、可能なものは索引づけられた属性として Lua に公開されます。get あるいは set として iface 関数が宣言されていても Lua の属性に割り当てることができない場合は、かわりに Lua の関数として公開されます。

Some functions are declared as 'get' or 'set' rather than 'fun' in the iface file. These are generally exposed to Lua as properties, e.g. `editor.TabSize = 8`. Some of the getters and setters also have a parameter. Where possible, these are exposed to Lua as indexed properties, e.g. `editor.StyleBold[SCE_PROPS_DEFAULT] = true`. However, if an iface function is declared as get / set but cannot be mapped to a Lua property, it is exposed as a Lua function instead.

iface の関数と属性についての完全な案内を解説に加えることが予定されています。従って iface ファイルを見る必要はなく、気持ちでテキストを扱えばよいのです。解説はまだ完成していませんが、一部の人にはよいプロジェクトとなるでしょう。よい雛形として Scintilla の解説書 を参考にするといいでしょう。加えて API ファイルもよいものです。

It is intended that a complete guide to the iface functions and properties should be added to the documentation, so you don't have to look at the iface file and do the mental text manipulation. This is not done yet, but would be a good project for someone. ScintillaDoc would be a good template to follow. An api file would also be a good addition.

The `scite` namespace includes the following functions:

      scite.Open(filename)
        - opens a file in a new buffer
        - activates the file's buffer if it is already opened.

      scite.SendEditor(SCI_constant, ...)
        - sends a message to the editor pane
        - equivalent to the corresponding iface function or property

      scite.SendOutput(SCI_constant, ...)
        - sends a message to the output pane

      scite.ConstantName(number)
        - returns the symbolic name of a Scintilla / SciTE constant

`Open` requires special care. When the buffer changes in SciTE, the Lua global namespace is reset to its initial state, and any extension script associated with the new buffer is loaded. Thus, when you call Open, this may change the environment in which your current script is running. When possible, you can avoid confusion by simply returning after scite.Open, but when that is not possible, just bear in mind that there are side effects. Local variables, unlike globals, will be retained after the buffer change until your script returns.

The `SendEditor` and `SendOuput` functions duplicate the functionality of the editor and output objects, providing access to these through an interface that is more familiar to Scintilla C++ developers. This may be useful for prototyping C++ code using Lua. Internally, `SendEditor` and `SendOutput` are translated to the corresponding iface function or property, so their arguments and return types are identical. (Although the calling convention for properties is obviously different.)

The ConstantName function may be useful when generating debug messages, or if extending the SciTE LuaExtension to support macro recording.

#### Lua を利用不可にする Disabling Lua

Lua は最初の実行時にはじめて読み込まれます。Lua が利用可能となる手段は `ext.lua.startup.script` 属性を通して設定されます。Lua のファイル名を `extension.filepattern` で設定するか、ツールコマンドの定義における拡張子処理構造を利用します(例: subsystem 3)。いずれも存在しない場合は Lua スクリプトエンジンは読み込まれず、SciTE は Lua が追加される前同様に動作します。

Lua is currently loaded just-in-time, before it is first used. The ways that Lua can become are through the `ext.lua.startup.script` property, by naming a lua file named in the `extension.filepattern` property, or by using the extension mechanism to define tool commands (i.e. subsystem 3). If you do not do any of these things, the Lua scripting engine is not loaded, and for all practical purposes, SciTE should behave as it did before Lua was added.

SciTE のビルドの際に Lua 対応を除いてしまうことが依然可能です。変数 `NO_LUA` をビルドの際に定義してください。MSVCの場合は `nmake -f scite.mak -DNO_LUA` 、GNU ツールの場合は `make NO_LUA=1` の形になります。

Nevertheless, it is still possible to build SciTE without the Lua support. To do this, simply define the variable `NO_LUA` when you build it, e.g. for MSVC, `nmake -f scite.mak -DNO_LUA`; or with GNU tools, `make NO_LUA=1`.