Skip to content

Instantly share code, notes, and snippets.

@RobTrew
Last active January 21, 2023 00:53
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save RobTrew/29857679b72b2f621130 to your computer and use it in GitHub Desktop.
Save RobTrew/29857679b72b2f621130 to your computer and use it in GitHub Desktop.
Toggle selected comments in OS X 10.10 Script Editor
// ROBIN TREW 2015 MIT License
// OSX 10.10 SCRIPT EDITOR – TOGGLE COMMENTS
// Add remove '// ' from before printing characters
// Depends on a library .scpt being saved at ~/Library/Script Libraries/DraftsSE.scpt
// See: See: http://support.foldingtext.com/t/writing-scripts-which-run-on-both-foldingtext-and-ios-drafts-4/652/7
// INCLUDE LIBRARY OF IOS DRAFTS-COMPATIBLE EDITOR FUNCTIONS:
function run() {
// PART 1: CODE SPECIFIC TO YOSEMITE SCRIPT EDITOR:
// SE implmentations of the basic iOS Drafts functions
// (Implementations of these functions for FoldingText and other editors with .js scripting at:
//
// getText() getSelectedLineRange()
// setText(string) getSelectedRange()
// getSelectedText() setSelectedRange(start, length)
// setSelectedText(string) getClipboard()
// getTextInRange(start, length) setClipboard(string)
// setTextInRange(start, length, string)
var app = Application("Script Editor"),
lstDoc = app.documents(),
oDoc = lstDoc.length ? lstDoc[0] : null;
if (!oDoc) return false;
//either var drafts = Library('DraftsSE'); // Assuming file saved at: ~/Library/Script Libraries/DraftsSE.scpt
// or locally:
drafts = {
getTextInRange: function (iStart, iLength) {
if (oDoc) return oDoc.text().substring(iStart, iStart + iLength);
},
setSelectedRange: function (iStart, iLength) {
if (oDoc) {
oDoc.selection = oDoc.text.characters.slice(iStart, iStart + iLength);
}
},
getSelectedLineRange: function () {
// works, but let me know if you see a shorter route :-)
var rgxLFCR=/[\r\n]/, dct, strFull, iFrom, iTo, lngChars;
if (oDoc) {
dct = oDoc.selection.characterRange();
strFull = oDoc.text();
lngChars = strFull.length;
iFrom = dct.x;
while (iFrom--)
if (strFull[iFrom].match(rgxLFCR)) break;
iFrom += 1;
iTo = dct.y - 1;
while (iTo++ < lngChars)
if (strFull[iTo].match(rgxLFCR)) break;
return [iFrom, (iTo - iFrom)];
}
},
setTextInRange: function (iStart, iLength, strText) {
if (oDoc) { // record the existing selection coordinates
var lngDelta = (strText.length - iLength) - 2,
oSeln = oDoc.selection,
dct = oSeln.characterRange(),
iFrom = dct.x,
iTo = dct.y;
try { // use the selection to edit elsewhere, then restore with any adjustment
oDoc.selection = oDoc.text.characters.slice(iStart, iStart + iLength);
oSeln.contents = strText;
oDoc.selection = oDoc.text.characters.slice(
(iStart < iFrom) ? iFrom + lngDelta : iFrom, ((iStart + iLength) < iTo) ? iTo + lngDelta : iTo
);
} catch (e) {}
}
}
};
app.includeStandardAdditions = true;
// Javascript '//' or Applescript '--' ?
strComment = (oDoc.language.id()[0] === 'j') ? '\/\/' : '--';
// PART 2: CODE COMPATIBLE WITH FOLDINGTEXT, DRAFTS, 1WRITER, TEXTWELL
function toggleComments(strCommentChars) {
// Javascript '//' or Applescript '--' ( this draft doesn't cover /* */ )
var rgxComment = new RegExp('^(\\s*)' + strCommentChars + '(\\s?)(\\s*)(?=\\S)', 'gm'),
rgxLeftSpace = /^(\s*)(?=\S)/,
rgxAddComment,
strAddComment,
lstLinesFromTo = drafts.getSelectedLineRange(),
iFrom = lstLinesFromTo[0],
lngSelnChars = lstLinesFromTo[1],
strLines = drafts.getTextInRange(iFrom, lngSelnChars),
blnCommented = rgxComment.test(strLines),
lstLines,
i, lngChars, oMatch, lngMatch,
lngMin = Infinity,
strLine,
strNew,lngLen;
if (blnCommented)
strNew = strLines.replace(rgxComment, '$1$3');
else {
// shortest whitespace to left ?
lstLines = strLines.split(/^/m);
i = lstLines.length;
while (i--) {
strLine = lstLines[i];
if (strLine) {
oMatch = rgxLeftSpace.exec(strLine);
if (oMatch) {
lngChars = oMatch[1].length;
if (lngChars < lngMin) lngMin = lngChars;
} else {
lngMin = 0;
break;
}
}
}
if (lngMin === Infinity) lngMin = 0;
// MAKE A REGEX TO INSERT THE COMMENT PATTERN N SPACE CHARS INTO THE LINE
// strAddComment = '^(' + Array(lngMin + 1).join('\\s') + ')';
// rgxAddComment = new RegExp(strAddComment, 'gm');
// strNew = strLines.replace(rgxAddComment, '$1' + strCommentChars + ' ');
strNew = strLines.replace(
new RegExp(
'^(' + Array(lngMin + 1).join('\\s') + ')', 'gm'
), '$1' + strCommentChars + ' '
);
}
drafts.setTextInRange(iFrom, lngSelnChars-1, strNew);
lngLen = strNew.length-1;
drafts.setSelectedRange(iFrom, lngLen);
return [iFrom, lngLen];
}
// MAIN
lstSeln = toggleComments(strComment);
drafts.setSelectedRange(lstSeln[0], lstSeln[1])
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment