| SciTE Director Interface

### Purpose.

Software development does not occur only at the single file level handled by SciTE. A developer will generally work on a group of related files together in the context of one project. Project manager functionality could be added to SciTE as it has to other editors but this would impose a particular view of how projects are to be managed including the format of project files. Instead, SciTE has an interface that can be used by project managers or similar applications to control SciTE. Any application that controls SciTE is referred to as a "Director".

The current Director interface only works on Windows. In the future, it should be possible to replace the low level interface and so make this interface available on other platforms.

There is currently one director application, Filerx, available.

This interface is implemented on top of the SciTE Extension Interface, in the file scite\win32\DirectorExtension.cxx.

### Direct connection, broadcasting and explicit return addresses.

One application at a time is the director of SciTE, controlling SciTE as it wishes. To support other communications techniques applications may broadcast to all active director interfaces. When doing so, each message should contain an explicit return address where replies to the broadcast message will be sent.

### Low level interface on Windows.

The Windows WM_COPYDATA message is used to transfer data between SciTE and a Director. The messages are sent between windows created by the two applications. SciTE uses a window that has no other purpose than to receive these messages. The lpData and cbData fields of the COPYDATASTRUCT are used to transfer a string between the two processes, with cbData holding the length of the string pointed to by lpData. The string does not have to be terminated with '\0'. The dwData should be 0.

Before messages can be sent from one application to the other, the window handle of the window to receive the message must be found. This is normally transferred when starting the other application as a command line parameter. Either application may start the other. SciTE makes its window handle available in the WindowID property and accepts a director.hwnd property as the window handle to which it sends data.

As an example of communicating the window handle, to install Filerx in the Tools menu of SciTE these properties could be used:

`command.name.0.*=Project Editor
command.0.*="C:\os\scite\bin\filerx.exe" "$(FileDir)" "$(WindowID)"
command.subsystem.0.*=2`

In the opposite direction, Filerx can start up SciTE with a command line that specifies its window handle as well as the file it wants edited:

`SciTE -director.hwnd=937846 c:\os\scite\src\SciTEBase.cxx`

Once one application has the window handle of the other application, it should send its window handle to the other application using an identity message as described later. Then both sides are able to send messages.

To broadcast a message on Windows, the set of active director interfaces can be found by broadcasting the "SciTEDirectorInterface" message and seeing which windows reply with the same value as that message. Example broadcast code:

unsigned int SDI = ::RegisterWindowMessage("SciTEDirectorInterface");
HWND w = ::GetWindow(::GetDesktopWindow(),GW_CHILD);
while (w) {
DWORD res = 0;
// Need time out to avoid hung applications
::SendMessageTimeout(w, SDI, 0, 0,
SMTO_NORMAL, 1000, &res);
if (res == static_cast<DWORD>(SDI)) {
// Replied with same SDI code so should
// understand SDI's version of WM_COPYDATA
::SendMessage(w,WM_COPYDATA,
(UINT)m_hWnd,(long)&cds);
}
w = ::GetWindow(w, GW_HWNDNEXT);
}

To advertise that a top level window supports the Director interface:

LRESULT PASCAL DirectorExtension_WndProc(HWND hWnd,
UINT iMessage, WPARAM wParam, LPARAM lParam) {
unsigned int SDI = ::RegisterWindowMessage("SciTEDirectorInterface");
if (iMessage == SDI) {
return SDI;
}
return ::DefWindowProc(hWnd, iMessage, wParam,lParam);
}

### Low level interface on GTK+.

This is not yet implemented. The proposed design uses an input fifo for each application supporting the director interface located in /tmp with a name using a pattern such as "/tmp/SciTE<PID>.director". This allows enumerating all active director interfaces and also opening a specific interface when the fifo name has been communicated through some other means such as a command line argument or an identity: command.

### High level interface.

Messages use C style escapes to represent control characters and ensure that only visible characters are transmitted apart from the use of '\n' to separate messages.

The string transmitted by the low level interface contains an optional return address surrounded by ':' characters, an action, a ':' character and an optional argument. The argument is often a file path. The ':' must be present even if there is no argument. For example, SciTE understands the message

`open:c:\\os\\scintilla\\include\\Scintilla.iface`

as a command to open the file "c:\os\scintilla\include\Scintilla.iface" just as if the user had performed this operation.

If the first character of the message is a ':' then up to the next ':' is a return address, so SciTE will reply to the message

`:73658:askfilename:`

by sending the filename being edited to the return address 73658 rather than to its director.

#### The actions understood by SciTE are:

askfilename: | Return the name of the file being edited.
askproperty:<key> | Return the value of a property.
close: | Close the current file.
closing: | Director is closing - SciTE closes if it was started by the director.
currentmacro:<string> | Set the current macro to name.
cwd: | Change the working directory.
enumproperties:dyn|local|user|base|embed | Enumerate all the properties in the argument set.
exportashtml:<path> | Save the document in HTML format as the indicated file.
exportasrtf:<path> | Save the document in RTF format as the indicated file.
find:<string> | Search for a string, select and show it.
goto:<lineNumber>[,<columnNumber>] | Move caret to a particular line and make it visible. If there is a column number then select the word at that column number or move the caret there if no word is present.
identity:<hwndDirector> | Sets the director window handle to which SciTE sends messages. The argument is in decimal.
insert:<value> | Display the value in the editor pane replacing the selection.
macrocommand:<command> | Execute a macro command. See the SciTE source code for the syntax of the command argument.
macroenable:<enable> | If enable, display menu commands in SciTE for recording and playing macros.
macrolist:<list> | Display a list for the user to choose from.
menucommand:<cmd> | Execute a menu command based on numeric ID.
open:<path> | Open the indicated file.
output:<value> | Display the value in the output pane replacing the selection.
property:<key>=<value> | Set a property to a value.
quit: | Shut down SciTE.
replaceall:<search>\000<replace> | Replace all instances of he search string in the document with the replace string.
saveas:<path> | Save the document as the indicated file.

#### The actions sent by SciTE are:

closing: | SciTE is closing.
dyn|local|user|base|embed:<key>=<value> | Set a property in a set to a value.
filename:<path> | The file being edited is path. This is the reply to the askfilename: command.
identity:<hwndSciTEReceiving> | SciTE indicates to the director the window handle to which it should send messages. The argument is in decimal.
macro:getlist | Retrieve the list of available macros which will be returned by the macrolist command.
macro:record:<details> | Start recording a macro. See the SciTE source code for the syntax of the details argument.
macro:run:<macroName> | Run the named macro.
macro:stoprecord | Stop recording a macro.
opened:<path> | SciTE has opened the indicated file.
switched:<path> | SciTE has switched buffers to the indicated file.
saved:<path> | SciTE has saved the indicated file.

In the future, more actions will be defined. Applications should ignore any actions that they do not understand.