Last active
December 3, 2024 10:40
-
-
Save RobTrew/5b374bc2ce14863c83dc to your computer and use it in GitHub Desktop.
Indent selected line(s) in OS X 10.10 Script Editor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ROBIN TREW 2015 MIT License | |
// OSX 10.10 SCRIPT EDITOR – INDENT SELECTED LINES (with Tab or 4 spaces) | |
// 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 ALL OR PART OF 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) {} | |
} | |
} | |
}; | |
// ------------------------------------------------------------------- | |
// PART 2: CODE COMPATIBLE WITH FOLDINGTEXT, DRAFTS, 1WRITER, TEXTWELL | |
function indentSelectedLines() { | |
var strDefaultIndent = '\t', | |
strIndent, | |
rgxLeftSpace = /^([ \t]+)(?=\S)/gm, | |
rgxStart = /^/gm, | |
lstLinesFromTo = drafts.getSelectedLineRange(), | |
iFrom = lstLinesFromTo[0], | |
lngSelnChars = lstLinesFromTo[1], | |
strLines = drafts.getTextInRange(iFrom, lngSelnChars), | |
oMatch = rgxLeftSpace.exec(strLines), | |
strGap = oMatch ? oMatch[1] : null, | |
i = strGap ? strGap.length : 0, | |
iTab = 0, | |
iSpace = 0; | |
// INDENTED WITH SPACES OR WITH TABS ? | |
if (strGap) { | |
while (i--) { | |
if (strGap[i] === '\t') iTab++; | |
else iSpace++; | |
} | |
strIndent = (iTab > iSpace) ? '\t' : ' '; | |
} else strIndent = strDefaultIndent; | |
// BUILD THE INDENTED TEXT | |
strNew = strLines.replace(rgxStart, strIndent); | |
// PLACE AND SELECT | |
drafts.setTextInRange(iFrom, lngSelnChars - 1, strNew); | |
drafts.setSelectedRange(iFrom, strNew.length - 1); | |
return true; | |
} | |
// MAIN | |
return indentSelectedLines(); | |
} |
For anyone else who wants to use this script, I have found by experimentation that all you need to do is save it to your ~/Library/Scripts/Applications/Script Editor
folder, and it is then available in the Script menu in the Apple menu bar.
I named the file "[SE] Indent JS Code.scpt
" to be obvious to me.
Then, select the lines in the SE document, and run this script.
Still looking for the "outdent" companion. . .
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@RobTrew:
Thanks for providing a great tool that the Mac Script Editor is missing.
However, I cannot understand how to install and use it.
The gist script/file title is "
indentlines.js
", but then you say to save to the Script Libraries as "DraftsSE.scp
t"Seems like the top level calling script would need to be in the ~/Library/Scripts folder so it could be from within the SE.
You don't state so, but I'm assuming that the user needs to select the text in a SE document, and then call your script.
Could you please be a bit more specific for people who don't know as much as you do about scripting?
And while I'm asking, does this tool, and any other, provide outdenting?
Thanks.