Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --Installation: Create an Automator service, paste this code into a "Run AppleScript" action, and save.
- --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
- --v4: Made more efficient by selecting text from the beginning if target length is shorter than modification length (when shortening only)
- --NOTES:
- --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.
- --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).
- --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.
- on run {input, parameters}
- try
- set debug to false
- if input's class is not list then
- set input to getHighlight(debug)
- end if
- tell application "System Events"
- --See if the clipboard has a number in it to use for the selection length
- set checkClipboard to the clipboard as text
- if my isNumString(checkClipboard) then
- set n to checkClipboard as integer
- else
- --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)
- set curProc to (name of first process whose frontmost is true)
- set n to my getintvalue()
- --And this is the only trick I've found to bring any window in an app back into focus
- do shell script "open -a '" & (curProc as string) & "'"
- delay 0.2
- end if
- --Check the length of the selected text passed in
- set character_count to count characters of ((input as string) as string)
- set lengthen to false
- set mod_length to character_count - n
- --Figure out whether the selection must be lengthened or shrunk
- if character_count is equal to 0 or n is greater than character_count then
- set lengthen to true
- set mod_length to n - character_count
- end if
- --See if we're in Terminal
- set isTerminal to ((name of first process where it is frontmost) as string) is equal to "Terminal"
- if isTerminal is true then
- if lengthen is true then
- set substr to (input as string)
- repeat mod_length times
- set substr to substr & "N"
- end repeat
- else
- set substr to text 1 thru n of (input as string)
- set substr to substr & (text (n + 1) thru character_count of (input as string))
- end if
- ignoring application responses
- display dialog "Length " & n & " is selected below:" default answer substr buttons {"OK"} default button 1 with title "Selected Character Position"
- end ignoring
- end if
- --Trick to make sure arrow presses affect the right side of the selection instead of the left
- if not (character_count is equal to 0 or n is greater than character_count) then
- key code 124 using {shift down}
- key code 123 using {shift down}
- key code 124 using {shift down}
- end if
- if lengthen is false and n is less than mod_length then
- if character_count is greater than 0 then
- key code 123
- end if
- repeat n times
- key code 124 using {shift down}
- end repeat
- else
- repeat mod_length times
- if lengthen is true then
- key code 124 using {shift down}
- else
- key code 123 using {shift down}
- end if
- end repeat
- end if
- delay 1
- end tell
- on error errstr
- display dialog errstr
- end try
- end run
- property mytitle : "Length of text to select"
- -- I am asking the user to provide an integer
- -- In case the user cancels the dialog, I return «missing value»
- on getintvalue()
- set dlgmsg to "How many characters would you like to select?:"
- try
- display dialog dlgmsg default answer "1" buttons {"Cancel", "Enter"} default button 2 with title mytitle
- on error
- -- User canceled
- return missing value
- end try
- set dlgresult to result
- set usrinput to text returned of dlgresult
- -- the user did not enter anything...
- if usrinput is "" then
- my getintvalue()
- else
- -- let's check if the user entered numbers only
- set nums to {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0"}
- set invalidchars to ""
- repeat with char in usrinput
- if char is not in nums then
- set invalidchars to invalidchars & char & space
- end if
- end repeat
- -- we found invalid characters
- if invalidchars is not "" then
- set errmsg to "We found the following characters in the given input. Please enter numbers only." & return & return & invalidchars & return
- my dsperrmsg(errmsg, "--")
- my getintvalue()
- else
- -- let's try to transform the user input into an integer
- try
- set intvalue to usrinput as integer
- return intvalue
- on error
- set errmsg to "We could not coerce the given input into an integer:" & return & return & usrinput & return
- my dsperrmsg(errmsg, "--")
- my getintvalue()
- end try
- end if
- end if
- end getintvalue
- -- I am displaying error messages to the user
- on dsperrmsg(errmsg, errnum)
- tell me
- activate
- display dialog errmsg & " (" & errnum & ")" buttons {"OK"} default button 1 with title mytitle with icon stop
- end tell
- end dsperrmsg
- -- isNumString :: String -> Bool
- on isNumString(s)
- try
- if class of s is string then
- set c to class of (s as number)
- c is real or c is integer
- else
- false
- end if
- on error
- false
- end try
- end isNumString
- on getHighlight(debug)
- --Save the current contents of the clipboard
- try
- set theSpare to the clipboard --as text
- on error
- set response to (display dialog "Warning: The contents of the clipboard will be lost." buttons {"Cancel", "OK"})
- if button returned of response is "OK" then
- set theSpare to ""
- end if
- end try
- set the clipboard to ""
- --Declare the variable we're going to return
- set selecTxt to ""
- tell application "System Events"
- --Initiate the copy
- keystroke "c" using {command down}
- --Wait up to 2 seconds for the copy to finish
- set done to "no"
- set waitnum to 0
- set waitInterval to 0.02
- set maxwaits to 100
- --Repeat while the clipboard contents have not changed
- repeat while done = "no"
- --Get the contents of the clipboard
- try
- set selecTxt to the clipboard as text
- end try
- --See if we're done or need to wait
- if waitnum is equal to maxwaits then
- set done to "yes"
- else if selecTxt is equal to "" then
- delay waitInterval
- set waitnum to waitnum + 1
- else
- set done to "yes"
- end if
- end repeat
- if debug is true then
- try
- display dialog "Copied text: " & (the clipboard as text)
- end try
- end if
- end tell
- --Restore the original clipboard contents
- set the clipboard to theSpare --as record
- if debug is true then
- try
- display dialog "The clipboard contents have been restored to " & (the clipboard as text)
- end try
- end if
- --Return the highlighted text
- return selecTxt
- end getHighlight
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement