Thursday, October 17, 2019

#1 2015-01-23 01:45:03 pm

McUsrII
Member
Registered: 2012-11-21
Posts: 3046
Website

Getting the Selection from TextEdit with UIScripting

Hello

This is a script that returns the selection of the front Text window of TextEdit, whether it is saved or not.

An insertion point for a text document are usually implemented as a list/array with a startValue, and an endValue. If there is no selection, then the endValue is one less than the startValue, if endValue is equal or greater than startValue then something is selected.

I have tried to return a selection object, that contains an insertion point as described above. I have also looked to how a selectionObject is implemented elsewhere, and added a property of my own. hasSel, to simplify the usage somewhat.

To be on the safe side, you'll have to check for the return value of null when using this, because the library handler will return null if the Preferences window of TextEdit is in front.

I have also implemented it as an AS 2.3 library, if you don't know how to use this, then, save it under the name "TextEdit" in the folder "Script Libraries" of your "Library" folder. You'll have to make that folder if it doesn't exist.

If it doesn't work, then TextEdit must be enabled for assistive devices.

The driver for the library script at the bottom, should explain the most of it.

Try it with:
* Some text selected
* No text selected
* The preferences window of TextEdit as its frontmost window.

Enjoy

Applescript:


use AppleScript version "2.3"
use scripting additions

script selectionObject
   property pos : {} -- consists of a start, end pair, that correlates with the characters of the text
   property theText : ""
   property hasSel : false
end script


to getSelection()
   set commence to false
   set o to my selectionObject
   set o's pos to {}
   set o's theText to ""
   set o's hasSel to false
   
   tell application id "com.apple.textedit"
       try
           if document of window 1 is not missing value then set commence to true
       end try
   end tell
   
   if commence then
       tell application id "sevs"
           tell application process "TextEdit"
               tell attribute "AXSelectedTextRange" of text area 1 of scroll area 1 of window 1 ¬
                   to set o's pos to its value
               if item 2 of o's pos ≥ item 1 of o's pos then
                   tell attribute "AXSelectedText" of text area 1 of scroll area 1 of window 1 ¬
                       to set o's theText to its value
                   set o's hasSel to true
               else
                   set o's theText to ""
               end if
           end tell
       end tell
       return o
   else
       return null
   end if
end getSelection

Applescript:


use AppleScript version "2.3"
use scripting additions
use ttxt : script "TextEdit"

-- Test run with some Text Selected
set selObj to ttxt's getSelection()
if selObj is not null then -- MANDATORY!
   log selObj's pos
   -- (*234, 491*)
   log selObj's theText
   (*
(*ou "makeCodestring for aSentence" first,
then test against all of your other code strings that you have in a list or something, which okCodeStrings kind of demonstrates, this is more laborious for your part, as I under
if there is a "collision" then*)

*)
   log selObj's hasSel
   (*true*)
   
   -- Test run with no text selected
   
   set selObj to ttxt's getSelection()
   
   log selObj's pos
   (*303, 302*)
   log selObj's theText
   (**)
   
   log selObj's hasSel
   (*false*)
else
   log "this time with the preferences window was in front"
end if


Filed under: selection, TextEdit

Offline

 

#2 2019-09-21 11:55:48 pm

KniazidisR
Member
Registered: 2019-03-03
Posts: 618

Re: Getting the Selection from TextEdit with UIScripting

The code above does not work anymore. The application's UI elements often change the object model, so to get selection in any application, which doesn't have selection property is far better to use a different, persistent solution:

Applescript:


set the clipboard to ""

tell application id "com.apple.textedit" -- any app id
   set appName to its name
   activate
   tell application "System Events" to tell process appName
       set visible to true
       keystroke "c" using command down
   end tell
end tell

set {aSelection, maxTimeOut} to {"", 0}

repeat while aSelection = ""
   set maxTimeOut to maxTimeOut + 0.1
   if maxTimeOut > 1 then return display notification "NOTHING SELECTED." with title "Do selection and run the script again" sound name "Frog"
   set aSelection to (the clipboard) as text
end repeat

Last edited by KniazidisR (2019-09-22 12:25:28 am)


macOS Mojave -- version 10.14.4
Safari -- version 12.1


Filed under: selection, TextEdit

Offline

 

#3 2019-09-22 04:16:45 am

Nigel Garvey
Moderator
From:: Warwickshire, England
Registered: 2002-11-20
Posts: 5064

Re: Getting the Selection from TextEdit with UIScripting

KniazidisR wrote:

The code above does not work anymore.


Hi KniazidisR.

McUsrII's script still works on my Mojave system, but there were some rogue characters in his post owing to MacScripter's current forum software using a different text encoding from that in use four-and-three-quarters years ago. I've now corrected these above.

McUsrII's script returns a script object whose properties are set to the front TextEdit document's selection range (pos), selected text (theText), and whether or not anything is actually selected (hasSel).

The selection range is synonymous with the insertion range and is a two-integer list. These integers can be thought of as character positions in the text, but actually represent the insertion points before and after these characters. Since the insertion cursor is always somewhere in the text, there's always a selection range, even when no actual characters are selected. A zero-width selection between two adjacent characters is indicated by the second range integer being one less than the first — eg. {397, 396}, indicating that the selection range stretches from the insertion point before character 397 to the insertion point after character 396, or that it both begins and ends between these characters. McUsrII takes this situation to mean there's no selection.

One disadvantage of his method (which also appears in a script I wrote for my own use) is that when there are multiple selections in the document, only the details of the first are returned.

Your script only returns the selected text, changes the contents of the clipboard (not necessarily a bad thing, but some scripters like to store the existing contents first and restore them afterwards), and doesn't always catch the new contents before the timeout. But when it works, the returned string does include the text of every selection in the document, each assigned to a new paragraph. For some reason, I can't get the "Frog" sound with the alert, but I think I may have silenced notifications on my system.  smile

I get slightly more reliable results with this version of your script:

Applescript:


set the clipboard to ""

tell application id "com.apple.textedit" -- any app id
   set appName to its name
   activate
end tell

tell application "System Events"
   tell application process appName to set frontmost to true
   keystroke "c" using {command down}
end tell

set {aSelection, maxTimeOut} to {"", 0}

repeat while aSelection = "" and maxTimeOut ≤ 1
   delay 0.2
   set maxTimeOut to maxTimeOut + 0.2
   set aSelection to (the clipboard as text)
end repeat
if maxTimeOut > 1 then display notification "NOTHING SELECTED." with title "Do selection and run the script again" sound name "Frog"
return aSelection


NG

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)