SciTE Extension Interface |
Some people want to create enhanced versions of the SciTE editor, while still receiving the benefits of new SciTE features. This could be for an editor designed for a particular environment such as developing games, to incorporate a scripting capability within SciTE or to allow SciTE to be controlled by another process through an IPC mechanism.
There are two example extensions. The SciTE Director Interface allows SciTE on Windows to be controlled by an external application such as a project manager. An integration of the Lua scripting language into SciTE was done using the Extension interface. This is not currently maintained although it may become active again in the future. The code is available from the Scintilla CVS server under the extlua project.
bool Initialise(ExtensionAPI *host_);
bool Finalise();
bool Clear();
bool Load(const char *filename);
bool OnOpen(const char *path);
bool OnSwitchFile(const char *path);
bool OnSave(const char *path);
bool OnChar(char ch);
bool OnExecute(const char *s);
bool OnSavePointReached();
bool OnSavePointLeft();
bool OnStyle(unsigned int, int, int, Accessor *);
bool OnDoubleClick();
bool OnUpdateUI();
bool OnMarginClick();
An extension must implement the Extension interface defined in scite/src/Extender.h Only the first 4 methods must be implemented although an implementation can be as simple as just returning false. The other methods have empty default implementations. Methods added to this interface in the future should have default implementations so existing extensions will continue to compile.
Each method returns a bool indicating whether the method handled all processing that is needed and so no additional processing is required. Normally, false is returned to indicate that further processing may be done.
The extension should use the Initialise and Finalise methods to allocate and deallocate resources. The ExtensionAPI pointer should be saved in the Initialise method so the extension can communicate back to SciTE.
The Clear and Load methods are used to support extensions that need to load a resource such as a script file when a file is opened. When a file is opened in SciTE, first the extension is asked to clear any data associated with the previous file through Clear. Then SciTE checks for a property called "extension" which matches the file name, so for x.cpp, looks for extension.*.cpp. A file with this name is searched for in standard property file locations and if found Load is called with the path as an argument. There is also a check for a "SciTEGlobal.lua" file but this is from when the Extension interface was only for Lua scripting and it will go away.
OnExecute is called only when an extension command is executed. These are indicated in properties as subsystem 3.
Other methods are called upon events occurring in SciTE allowing an extension to respond to those events.
enum Pane { paneEditor=1, paneOutput=2, paneFindOutput=3 };
sptr_t Send(Pane p, unsigned int msg, uptr_t wParam=0, sptr_t lParam=0);
char *Range(Pane p, int start, int end);
void Remove(Pane p, int start, int end);
void Insert(Pane p, int pos, const char *s);
void Trace(const char *s);
char *Property(const char *key);
void SetProperty(const char *key, const char *val);
uptr_t GetInstance();
void ShutDown();
void Perform(const char *actions);
An extension can call back into SciTE using this interface which is a simplified way to access the functionality of SciTE.
As well as the normal editor pane and output pane, this interface allows for a future feature where a third pane may be used for the output of search commands. This is currently mapped to the output pane.
Send allows sending messages to the Scintilla control contained in each pane.
Range retrieves text from the pane. This must be deleted with delete[]. Remove and Insert are used to remove and insert text in a pane.
Trace displays a string at the end of the output pane.
SciTE's properties can be read and written with Property and SetProperty. The result from Property should be deleted with delete[].
GetInstance is Windows specific and returns the HINSTANCE of the application which is needed when accessing platform facilities.
ShutDown is equivalent to the user choosing the Quit menu item. If there are any unsaved files loaded, then the user is asked whether to save them and may cancel from this dialog. So under some circumstances, the application will continue to run after ShutDown is called.
Perform takes a string containing an action, a ':' character, and an argument. Currently the only known action is open and then the argument is a path. This is used by the Director extension to relay commands from another application. In the future more actions will be possible through this method.
Extensions are currently added explicitly by code in the start up function. On Windows, the DirectorExtension is attached with code similar to this simplified example:
DirectorExtension director;
Extension *extender = &director;
//...
SciTEWin MainWind(extender);
It would be better to move to an implicit attachment mechanism similar to the way lexers are attached to Scintilla, determining which extensions are used by simply linking their object files into SciTE. It would also be good to allow run-time attachment of extensions housed in DLLs or shared object libraries.
SciTE only supports one extension at a time. If there is a need to support multiple extensions, then a multiplexer extension can be used. This is a simple extension that maintains a list of extensions and calls each in turn for each method. Once an extension returns true indicating processing should stop, the multiplexer returns without traversing any remaining list members.