hepcat72

Modify selected text length automator applescript v3

Feb 28th, 2018
216
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.  
  4. --NOTES:
  5. --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.
  6. --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).
  7. --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.
  8.  
  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 i9n 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.             repeat mod_length times
  71.                 if lengthen is true then
  72.                     key code 124 using {shift down}
  73.                 else
  74.                     key code 123 using {shift down}
  75.                 end if
  76.             end repeat
  77.             delay 1
  78.         end tell
  79.     on error errstr
  80.         display dialog errstr
  81.     end try
  82.    
  83. end run
  84.  
  85.  
  86.  
  87. property mytitle : "Length of text to select"
  88.  
  89. -- I am asking the user to provide an integer
  90. -- In case the user cancels the dialog, I return «missing value»
  91. on getintvalue()
  92.     set dlgmsg to "How many characters would you like to select?:"
  93.     try
  94.         display dialog dlgmsg default answer "1" buttons {"Cancel", "Enter"} default button 2 with title mytitle
  95.     on error
  96.         -- User canceled
  97.         return missing value
  98.     end try
  99.     set dlgresult to result
  100.     set usrinput to text returned of dlgresult
  101.     -- the user did not enter anything...
  102.     if usrinput is "" then
  103.         my getintvalue()
  104.     else
  105.         -- let's check if the user entered numbers only
  106.         set nums to {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0"}
  107.         set invalidchars to ""
  108.         repeat with char in usrinput
  109.             if char is not in nums then
  110.                 set invalidchars to invalidchars & char & space
  111.             end if
  112.         end repeat
  113.         -- we found invalid characters
  114.         if invalidchars is not "" then
  115.             set errmsg to "We found the following characters in the given input. Please enter numbers only." & return & return & invalidchars & return
  116.             my dsperrmsg(errmsg, "--")
  117.             my getintvalue()
  118.         else
  119.             -- let's try to transform the user input into an integer
  120.             try
  121.                 set intvalue to usrinput as integer
  122.                 return intvalue
  123.             on error
  124.                 set errmsg to "We could not coerce the given input into an integer:" & return & return & usrinput & return
  125.                 my dsperrmsg(errmsg, "--")
  126.                 my getintvalue()
  127.             end try
  128.         end if
  129.     end if
  130. end getintvalue
  131.  
  132. -- I am displaying error messages to the user
  133. on dsperrmsg(errmsg, errnum)
  134.     tell me
  135.         activate
  136.         display dialog errmsg & " (" & errnum & ")" buttons {"OK"} default button 1 with title mytitle with icon stop
  137.     end tell
  138. end dsperrmsg
  139.  
  140. -- isNumString :: String -> Bool
  141. on isNumString(s)
  142.     try
  143.         if class of s is string then
  144.             set c to class of (s as number)
  145.             c is real or c is integer
  146.         else
  147.             false
  148.         end if
  149.     on error
  150.         false
  151.     end try
  152. end isNumString
  153.  
  154. on getHighlight(debug)
  155.    
  156.     --Save the current contents of the clipboard
  157.     try
  158.         set theSpare to the clipboard --as text
  159.     on error
  160.         set response to (display dialog "Warning: The contents of the clipboard will be lost." buttons {"Cancel", "OK"})
  161.         if button returned of response is "OK" then
  162.             set theSpare to ""
  163.         end if
  164.     end try
  165.     set the clipboard to ""
  166.     --Declare the variable we're going to return
  167.     set selecTxt to ""
  168.    
  169.     tell application "System Events"
  170.         --Initiate the copy
  171.         keystroke "c" using {command down}
  172.        
  173.         --Wait up to 2 seconds for the copy to finish
  174.         set done to "no"
  175.         set waitnum to 0
  176.         set waitInterval to 0.02
  177.         set maxwaits to 100
  178.        
  179.         --Repeat while the clipboard contents have not changed
  180.         repeat while done = "no"
  181.             --Get the contents of the clipboard
  182.             try
  183.                 set selecTxt to the clipboard as text
  184.             end try
  185.            
  186.             --See if we're done or need to wait
  187.             if waitnum is equal to maxwaits then
  188.                 set done to "yes"
  189.             else if selecTxt is equal to "" then
  190.                 delay waitInterval
  191.                 set waitnum to waitnum + 1
  192.             else
  193.                 set done to "yes"
  194.             end if
  195.            
  196.         end repeat
  197.        
  198.         if debug is true then
  199.             try
  200.                 display dialog "Copied text: " & (the clipboard as text)
  201.             end try
  202.         end if
  203.     end tell
  204.    
  205.     --Restore the original clipboard contents
  206.     set the clipboard to theSpare --as record
  207.    
  208.     if debug is true then
  209.         try
  210.             display dialog "The clipboard contents have been restored to " & (the clipboard as text)
  211.         end try
  212.     end if
  213.    
  214.     --Return the highlighted text
  215.     return selecTxt
  216.    
  217. end getHighlight
Advertisement
Add Comment
Please, Sign In to add comment