I’m currently using this to add single-line comments:
tell application "AppleScript Editor"
set sel to contents of selection of document 1
end tell
if sel = "" then return
set l to paragraphs of sel
set c to count l
if item -1 of l = "" then set c to c - 1
repeat with i from 1 to c
set item i of l to "-- " & item i of l
end repeat
set text item delimiters to return
tell application "AppleScript Editor"
set contents of selection of document 1 to l as text
end tell
How would you extend this into something like Toggle Comment in TextMate’s Source bundle? If all lines are already commented, it uncomments them (once) ” otherwise it adds eg "-- " to the start of each line.
This reverses whole-line commenting within the selection on a line-by-line basis:
tell application "AppleScript Editor" to set sel to contents of selection of document 1
if sel = "" then return
set l to paragraphs of sel
set c to count l
if item -1 of l = "" then set c to c - 1
set astid to AppleScript's text item delimiters
ignoring white space -- Makes 'begins with' ignore any leading tabs.
repeat with i from 1 to c
set thisLine to item i of l
if (thisLine begins with "--") then
if (thisLine begins with "-- ") then
set AppleScript's text item delimiters to "-- "
else
set AppleScript's text item delimiters to "--"
end if
if (thisLine's text items is {"", ""}) then
set item i of l to ""
else
set item i of l to text from text item 2 to -1 of thisLine
end if
else
set item i of l to "-- " & thisLine
end if
end repeat
end ignoring
set text item delimiters to return
tell application "AppleScript Editor" to set contents of selection of document 1 to l as text
set AppleScript's text item delimiters to astid
The standard (not line by line) behavior could be more convenient though. (If a selection has both commented and uncommented lines, the already commented ones are commented again.)
It could also support removing (* *) and # style comments, or – if # is the preferred style.
Maybe most importantly, it could apply for the current line if there’s no selection. Is there a better way than this?
if sel = "" then
try
tell application "System Events"
key code 123 using {command down, shift down}
key code 124 using {command down, shift down}
end tell
on error
return
end try
end if
As a matter of interest, the two ‘key code’ commands can be combined:
tell application "AppleScript Editor" to set sel to contents of selection of document 1
if (sel = "") then
tell application "System Events" to key code {123, 124} using {command down, shift down}
tell application "AppleScript Editor" to set sel to contents of selection of document 1
end if
But for the same effect without System Events:
tell application "AppleScript Editor"
tell document 1
set sel to contents of selection
if (sel = "") then
set theText to its text
set cursorPos to beginning of (get character range of selection)
set cursorLine to (count (text 1 thru cursorPos of theText) each paragraph)
set sel to paragraph cursorLine of theText
-- This is possible:
-- set selection to paragraph cursorLine of its text
-- But to exclude the line-ending, like the System Events method:
set lineLen to (count sel)
if (lineLen > 0) then
set b to (count text 1 thru paragraph cursorLine of theText)
set a to b - lineLen + 1
set selection to characters a thru b of its text
end if
end if
end tell
end tell
set text item delimiters to linefeed
set nl to {linefeed, return}
tell application "AppleScript Editor" to tell document 1
set txt to its text
if txt is "" then
set contents of selection to "--"
set selection to insertion point 3
return
end if
set {chr1, chr2} to character range of selection
if chr1 is 0 then
set p1 to 1
else
set p1 to count paragraphs of text 1 thru chr1 of txt
end if
if chr2 is 0 then
set p2 to 1
else
set p2 to count paragraphs of text 1 thru chr2 of txt
if nl contains item chr2 of txt and p1 is not p2 then set p2 to p2 - 1
end if
set selparas to paragraphs p1 thru p2 of txt
set selection to paragraphs p1 thru p2
set qf to quoted form of (selparas as text)
set un to (do shell script "echo " & qf & " | tr -d ' ' | sed '/^$/d' | sed '/^#/d' | sed '/^--/d'") is ""
if un then
set out to do shell script "/bin/bash -c " & quoted form of ("echo " & qf & " | sed 's/^\\([ | ]*\\)--[ | ]*/\\1/'g | sed 's/^\\([ | ]*\\)#[ | ]*/\\1/'g")
else
set out to do shell script "/bin/bash -c " & quoted form of ("echo " & qf & " | sed 's/^\\( *\\)/\\1--/'g")
end if
set contents of selection to out & linefeed
set {chr1, chr2} to character range of selection
set selection to insertion point chr2
end tell