Stefans Tools

Useful open source tools that make your life easier

JavaScript Plugins

BowPad can use plugins and scripts written in JavaScript (JScript) or VBScript. It uses the Windows Scripting Host (WSH) to handle the plugins.

To be used as a plugin in BowPad, the script must implement a few callback functions. The callbacks are optional to implement, but depending on what the plugin should accomplish you will have to implement at least some of them.

To access BowPad and its data, an object named "BowPad" is available and provides a lot of functions a plugin can call.

Start

Plugins are loaded from a folder named plugins, and each plugin is stored in its own folder. If you're using the portable version of BowPad, this folder is located in the same place the BowPad.exe file is stored. If you have installed BowPad with the installer, the folder is stored in %APPDATA%\BowPad\plugins.

First, create a folder for your plugin. The foldername must be the name of your plugin, e.g. pluginname. Inside that folder you have to create one file that describes your plugin, named pluginname.desc.
The first line of this file is the version of your plugin in decimal majorversion * 100 + minorversion. E.g., version 1.4 would be written as 104.
The second line is the minimum version of BowPad the plugin requires to run. So it must be at least 200 since plugins were introduced in BowPad 2.0.
The following lines are used to describe the plugin, what it does, who's the author, where to find more info. Basically you can write here anything you like: that text is shown in the plugins config dialog when the user clicks on the plugin as an info text.

The second file you have to create is the plugin script itself. The name of the file is used as the name for the menu item in BowPad. It must have either the extension .bpj if the script is written in JScript, or .bpv if the script is written in VBScript.

Callback functions

// returns the version of the plugin
// this callback is not optional! If you fail to implement this, the plugin
// config dialog won't work properly with your plugin
function Version() { return 100; }

// this is the main function that gets executed when the command is run, i.e.
// the button is clicked
function Execute()
{
    // execute whatever the plugin should do here,
    // return true if the command was successful or false if it didn't run
    // successfully
    return true;
}

// return true if the plugin command is enabled (used for the button)
// note: not used yet by BowPad, but planned for the future
function IsEnabled() { return true; }

// return true if the plugin button should appear as checked
// note: not used yet by BowPad, but planned for the future
function IsChecked() { return true; }

// called just before BowPad exits
function OnClose() { return; }

// called after BowPad has fully initialized
function AfterInit() { return; }

// called just before a document is closed
function OnDocumentClose(index) { return; }

// called after a document was opened
function OnDocumentOpen(index) { return; }

// called after a document was saved
function OnDocumentSave(index) { return; }

// called on a timer event
function OnTimer(id) { return; }

// notification from the Scintilla control
function ScintillaNotify(code, position, ch, modifiers, modificationType, text, length, linesAdded, message, wParam, lParam, line, foldLevelNow, foldLevelPrev, margin, listType, x, y, token, annotationLinesAdded, updated)
{
    // for a description of the parameters, see the Scintilla
    // documentation here:
    // http://www.scintilla.org/ScintillaDoc.html#Notifications
    return;
}

// notification about tabs
function TabNotify(code, tabOrigin)
{
    return;
}
        

BowPad functions

To access BowPad and its data, an object named "BowPad" is available and provides a lot of functions a plugin can call.

First a list of functions and properties for the main component of BowPad:

// shows a message box with the specified message text
BowPad.alert("message");
// outputs the specified text to the debug output of an attached debugger
// or tools like dbgView (https://technet.microsoft.com/en-us/sysinternals/bb896647.aspx)
BowPad.debugprint("message");
// Sets the tab index at which the next new tab/document is inserted
BowPad.SetInsertionIndex(int);
// activates the tab at the specified index
BowPad.TabActivateAt(int);
// updates the tab at the specified index, ensuring the tab name and state are drawn correctly
BowPad.UpdateTab(int);
// returns the document ID of the specified tab index
var docID = BowPad.GetDocIdOfCurrentTab(int);
// returns the document ID of the specified tab index
var docID = BowPad.GetDocIDFromTabIndex(index);
// returns the document ID for the specified path
var docID = BowPad.GetDocIDFromPath("C:/file.txt");
// returns the tab index for the specified document ID
var tabIndex = BowPad.GetTabIndexFromDocID(id);
// returns the index of the currently active/shown tab
var activeTab = BowPad.GetActiveTabIndex(int);
// returns the number of open tabs/documents
var tabcount = BowPad.GetTabCount();
// returns the current title string
var title = BowPad.GetCurrentTitle();
// returns the title string of the specified tab
var title = BowPad.GetTitleForTabIndex(int);
// returns the title string of the specified document
var title = BowPad.GetTitleForDocID(int);
// sets the title of the current tab
BowPad.SetCurrentTitle("new title");
// closes the specified tab. If force is true, the tab is closed without
// asking to save it first even if it's modified
BowPad.CloseTab(tabindex, false);
// Property that contains the number of open documents
var count = BowPad.DocumentCount;
// Property that indicates whether there's a document active
// In some callbacks it's possible that there is no tab active, this is
// to check for that
var bActive = BowPad.HasActiveDocument;
// Property that indicates whether the active tab has a document ID assigned to it.
// In some callbacks it's possible that even if there's a tab active, no document
// is assigned to it yet.
var bHasID = BowPad.HasDocumentID;
// forces an update of the status bar. If true is passed, the whole status bar
// info is read and updated. If false is passed, only the line and doc info is updated.
BowPad.UpdateStatusBar(bEverything);
// sets up the configured lexer for the specified language
BowPad.SetupLexerForLang("html");
// clears the info for the doc scrollbar: all coloring is cleared
BowPad.DocScrollClear();
// adds a color to the doc scrollbar
// type specifies the information type: 1 = selected text, 2 = bookmark, 3 = search matches
// line is the line number the info is for
// color is an RGB value
BowPad.DocScrollAddLineColor(type, line, color);
// redraws the doc scrollbar to show the set information
BowPad.DocScrollUpdate();
// removes color info from the doc scrollbar for the specified type and line
BowPad.DocScrollRemoveLine(type, line);
// moves the cursor to the specified line
BowPad.GotoLine(line);
// centers the text between the minPos and maxPos in the window
BowPad.Center(minPos, maxPos);
// moves the cursor to the corresponding brace
BowPad.GotoBrace();
// returns a timer ID to be used in the SetTimer() function
var timerID = BowPad.GetTimerID();
// sets a timer. The OnTimer() callback is called whenever the timer elapses
BowPad.SetTimer(timerID, milliseconds);
// opens the specified file, if mru is true, the file is added to the MRU list
BowPad.OpenFile("C:/file.ext", true);
// reloads the specified tab with the specified encoding. If the encoding is -1
// then the encoding is determined from the file content.
BowPad.ReloadTab(tab, 65001);   // reload tab with UTF8 encoding
// saves the currently active tab
// if saveas is true, the save-as dialog is shown unconditionally. If saveas
// is false, the save-as dialog is only shown if the tab was never saved before
// and has no file path specified.
BowPad.SaveCurrentTab(saveas);
// Invalidates the state of the plugin button. Call this if the look of
// the button needs changing.
BowPad.InvalidateState();
    

BowPad uses the Scintilla editor component. A plugin can access that component via special functions provided by the "BowPad" object. Please refer to the Scintilla documentation for detailed information about the available commands and parameters: http://www.scintilla.org/ScintillaDoc.html

The "BowPad" component provides most of the Scintilla functions. The naming of the functions is a modified version of the SCI_ functions of the Scintilla component.

For example, the Scintilla function SCI_SETSELECTIONSTART(int position) is named SciSetSelectionStart(int) in the BowPad object. Basically the function names are the names of the original Scintilla functions without the _ in the name. The parameters are either interger, bools or strings and the same as in the Scintilla documentation.

Parameters in the Scintilla docs that are shown as <unused> are omitted in the BowPad object function. Also "Get" functions that have a char * text parameter are treated differently: the strings are returned directly by the BowPad object function as the return value, so the pointer param must be omitted. For example: SCI_GETSELTEXT(<unused>, char *text) becomes var selText = SciGetSelText().

Some Scintilla functions take structs as parameters or return values in structs. These are converted differently to "BowPad" functions and listed here:

// returns the specified range of text, between the minPos position and the
// maxPos position
var sText = BowPad.SciGetTextRange(minPos, maxPos);
// returns the char at the specified position
// Note: BowPad sets the Scintilla control to UTF8 encoding, so it's
// possible that a char isn't complete because only the first byte
// is returned, and utf8 chars can use multiple bytes.
// use SciGetTextRange() instead if you're dealing with non-ASCII text
var sChar = BowPad.SciGetCharAt(position);
// finds the text
var foundPos = BowPad.SciFindText(flags, minPos, maxPos, "text to search for");