Advertisement
hepcat72

Modify selected text length automator applescript v4

Feb 28th, 2018
266
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --Installation: Create an Automator service, paste this code into a "Run AppleScript" action, and save.
  2. --How to use it: 1. Copy a number indicating the length you want the selection to be. 2. Select the region of text where you want the copied length to be selected. 3. Right-click the selection and select this service
  3. --v4: Made more efficient by selecting text from the beginning if target length is shorter than modification length (when shortening only)
  4.  
  5. --NOTES:
  6. --If the contents of the clipboard is not a number, you'll be prompted to enter a length, although this feature has not been tested.
  7. --If the selected text is in Terminal.app, the modified selection will display in a dialog window (because the arrow keys are used for the selection modification and that doesn't work in Terminal).  Also, if the target selection length is longer than the current selection, the remainder will be filled in with N's (because this was originally made for DNA strings).
  8. --If input is not supplied, this script will backup the current clipboard, copy the current selection to get the currently selected text, then restore the clipboard.
  9.  
  10. on run {input, parameters}
  11.    
  12.     try
  13.         set debug to false
  14.         if input's class is not list then
  15.             set input to getHighlight(debug)
  16.         end if
  17.        
  18.         tell application "System Events"
  19.             --See if the clipboard has a number in it to use for the selection length
  20.             set checkClipboard to the clipboard as text
  21.             if my isNumString(checkClipboard) then
  22.                 set n to checkClipboard as integer
  23.             else
  24.                 --Get the name of the frontmost application so we can bring the front window back into focus after the dialog window goes away (which surprisingly, is not the default behavior)
  25.                 set curProc to (name of first process whose frontmost is true)
  26.                
  27.                 set n to my getintvalue()
  28.                
  29.                 --And this is the only trick I've found to bring any window in an app back into focus
  30.                 do shell script "open -a '" & (curProc as string) & "'"
  31.                 delay 0.2
  32.             end if
  33.            
  34.             --Check the length of the selected text passed in
  35.             set character_count to count characters of ((input as string) as string)
  36.            
  37.             set lengthen to false
  38.             set mod_length to character_count - n
  39.             --Figure out whether the selection must be lengthened or shrunk
  40.             if character_count is equal to 0 or n is greater than character_count then
  41.                 set lengthen to true
  42.                 set mod_length to n - character_count
  43.             end if
  44.            
  45.             --See if we're in Terminal
  46.             set isTerminal to ((name of first process where it is frontmost) as string) is equal to "Terminal"
  47.            
  48.             if isTerminal is true then
  49.                 if lengthen is true then
  50.                     set substr to (input as string)
  51.                     repeat mod_length times
  52.                         set substr to substr & "N"
  53.                     end repeat
  54.                 else
  55.                     set substr to text 1 thru n of (input as string)
  56.                     set substr to substr & (text (n + 1) thru character_count of (input as string))
  57.                 end if
  58.                 ignoring application responses
  59.                     display dialog "Length " & n & " is selected below:" default answer substr buttons {"OK"} default button 1 with title "Selected Character Position"
  60.                 end ignoring
  61.             end if
  62.            
  63.             --Trick to make sure arrow presses affect the right side of the selection instead of the left
  64.             if not (character_count is equal to 0 or n is greater than character_count) then
  65.                 key code 124 using {shift down}
  66.                 key code 123 using {shift down}
  67.                 key code 124 using {shift down}
  68.             end if
  69.            
  70.             if lengthen is false and n is less than mod_length then
  71.                 if character_count is greater than 0 then
  72.                     key code 123
  73.                 end if
  74.                 repeat n times
  75.                     key code 124 using {shift down}
  76.                 end repeat
  77.             else
  78.                 repeat mod_length times
  79.                     if lengthen is true then
  80.                         key code 124 using {shift down}
  81.                     else
  82.                         key code 123 using {shift down}
  83.                     end if
  84.                 end repeat
  85.             end if
  86.             delay 1
  87.         end tell
  88.     on error errstr
  89.         display dialog errstr
  90.     end try
  91.    
  92. end run
  93.  
  94.  
  95.  
  96. property mytitle : "Length of text to select"
  97.  
  98. -- I am asking the user to provide an integer
  99. -- In case the user cancels the dialog, I return «missing value»
  100. on getintvalue()
  101.     set dlgmsg to "How many characters would you like to select?:"
  102.     try
  103.         display dialog dlgmsg default answer "1" buttons {"Cancel", "Enter"} default button 2 with title mytitle
  104.     on error
  105.         -- User canceled
  106.         return missing value
  107.     end try
  108.     set dlgresult to result
  109.     set usrinput to text returned of dlgresult
  110.     -- the user did not enter anything...
  111.     if usrinput is "" then
  112.         my getintvalue()
  113.     else
  114.         -- let's check if the user entered numbers only
  115.         set nums to {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0"}
  116.         set invalidchars to ""
  117.         repeat with char in usrinput
  118.             if char is not in nums then
  119.                 set invalidchars to invalidchars & char & space
  120.             end if
  121.         end repeat
  122.         -- we found invalid characters
  123.         if invalidchars is not "" then
  124.             set errmsg to "We found the following characters in the given input. Please enter numbers only." & return & return & invalidchars & return
  125.             my dsperrmsg(errmsg, "--")
  126.             my getintvalue()
  127.         else
  128.             -- let's try to transform the user input into an integer
  129.             try
  130.                 set intvalue to usrinput as integer
  131.                 return intvalue
  132.             on error
  133.                 set errmsg to "We could not coerce the given input into an integer:" & return & return & usrinput & return
  134.                 my dsperrmsg(errmsg, "--")
  135.                 my getintvalue()
  136.             end try
  137.         end if
  138.     end if
  139. end getintvalue
  140.  
  141. -- I am displaying error messages to the user
  142. on dsperrmsg(errmsg, errnum)
  143.     tell me
  144.         activate
  145.         display dialog errmsg & " (" & errnum & ")" buttons {"OK"} default button 1 with title mytitle with icon stop
  146.     end tell
  147. end dsperrmsg
  148.  
  149. -- isNumString :: String -> Bool
  150. on isNumString(s)
  151.     try
  152.         if class of s is string then
  153.             set c to class of (s as number)
  154.             c is real or c is integer
  155.         else
  156.             false
  157.         end if
  158.     on error
  159.         false
  160.     end try
  161. end isNumString
  162.  
  163. on getHighlight(debug)
  164.    
  165.     --Save the current contents of the clipboard
  166.     try
  167.         set theSpare to the clipboard --as text
  168.     on error
  169.         set response to (display dialog "Warning: The contents of the clipboard will be lost." buttons {"Cancel", "OK"})
  170.         if button returned of response is "OK" then
  171.             set theSpare to ""
  172.         end if
  173.     end try
  174.     set the clipboard to ""
  175.     --Declare the variable we're going to return
  176.     set selecTxt to ""
  177.    
  178.     tell application "System Events"
  179.         --Initiate the copy
  180.         keystroke "c" using {command down}
  181.        
  182.         --Wait up to 2 seconds for the copy to finish
  183.         set done to "no"
  184.         set waitnum to 0
  185.         set waitInterval to 0.02
  186.         set maxwaits to 100
  187.        
  188.         --Repeat while the clipboard contents have not changed
  189.         repeat while done = "no"
  190.             --Get the contents of the clipboard
  191.             try
  192.                 set selecTxt to the clipboard as text
  193.             end try
  194.            
  195.             --See if we're done or need to wait
  196.             if waitnum is equal to maxwaits then
  197.                 set done to "yes"
  198.             else if selecTxt is equal to "" then
  199.                 delay waitInterval
  200.                 set waitnum to waitnum + 1
  201.             else
  202.                 set done to "yes"
  203.             end if
  204.            
  205.         end repeat
  206.        
  207.         if debug is true then
  208.             try
  209.                 display dialog "Copied text: " & (the clipboard as text)
  210.             end try
  211.         end if
  212.     end tell
  213.    
  214.     --Restore the original clipboard contents
  215.     set the clipboard to theSpare --as record
  216.    
  217.     if debug is true then
  218.         try
  219.             display dialog "The clipboard contents have been restored to " & (the clipboard as text)
  220.         end try
  221.     end if
  222.    
  223.     --Return the highlighted text
  224.     return selecTxt
  225.    
  226. end getHighlight
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement