I needed a way, this morning, of extending the selection (by script) to the previous and following blank lines.
This is not quite the same as selecting a paragraph – a block between empty lines may contain more than one LF-delimited paragraphs.
For the paragraph case we can use Jesse’s rich set of built in commands:
property pstrJS : "
function(editor) {
editor.performCommand('selectParagraph');
}
"
on run
tell application "FoldingText"
tell front document to (evaluate script pstrJS)
end tell
end run
For the other case (selecting back to the previous empty line (or start of doc), and forward to the next empty line, or end of doc), one way is to use nodePaths to find the previous and next gaps in the text:
'//@id=' + idSelnStart + '/preceding::(@type=empty)[-1]',
'//@id=' + idSelnEnd + '/following::(@type=empty)[0]',
[-1]
means ‘the last line that matches that pattern’, and
[0]
is ‘the first line that matches that pattern’.
The full script might look like this:
property pblnDebug : false
property pstrJS : "
function(editor, options) {
function selectBlock(editor) {
// select back to previous gap (or start of doc)
// and forward to next gap (or end of doc)
var rngSeln = editor.selectedRange(),
idSelnStart = rngSeln.startNode.id,
idSelnEnd = rngSeln.endNode.id,
// PATHS: PREVIOUS GAP, AND NEXT GAP
strPathPrevGap = '//@id=' + idSelnStart + '/preceding::(@type=empty)[-1]',
strPathNextGap = '//@id=' + idSelnEnd + '/following::(@type=empty)[0]',
tree = editor.tree(),
lstBefore = tree.evaluateNodePath(strPathPrevGap),
lstAfter = tree.evaluateNodePath(strPathNextGap),
lngFrom, lngTo, rngNew;
// most recent empty line, or start of doc
if (lstBefore.length) {
lngFrom = lstBefore[0].lineTextStart()+1;
} else {
lngFrom = 0;
}
// next empty line, or end of doc
if (lstAfter.length) {
lngTo = lstAfter[0].lineTextStart()-1;
} else {
lngTo = tree.textLength();
}
// define the range by start position and length
rngNew = tree.createRangeFromLocation(lngFrom, lngTo-lngFrom);
// and select it
editor.setSelectedRange(rngNew);
return true;
}
return selectBlock(editor);
}
"
on run
tell application "FoldingText"
set varResult to missing value
if not pblnDebug then
set lstDocs to documents
if lstDocs ≠ {} then
tell item 1 of lstDocs
set varResult to (evaluate script pstrJS)
end tell
end if
else
-- debug script automatically refers to the SDK version of the editor
-- which must be open: FoldingText > Help > SDK > Run Editor
set varResult to (debug script pstrJS)
end if
return varResult
end tell
end run