Monday, December 18, 2017

#1 2017-12-03 04:10:45 pm

Joy
Member
From:: South Tirol
Registered: 2008-07-04
Posts: 542
Website

Place Cursor at beginning of paragraph n

Hi,
Is it possible to place the cursor at the beginning of a particular paragraph in any application,
Let's say in "Script Editor" ?

Offline

 

#2 2017-12-05 06:25:07 am

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

Re: Place Cursor at beginning of paragraph n

Joy wrote:

Let's say in "Script Editor" ?


Applescript:

-- Tested with SE 2.10 in 10.13.1.

set targetParagraphNumber to 12

delay 5 -- For testing only. Use the time to bring the target document to the front.

tell document 1 of application "Script Editor"
   if (targetParagraphNumber is 1) then
       -- Use the index of the insertion point at the beginning of the text.
       set i to 1
   else
       -- Get the index of the insertion point after the line ending before the target paragraph …
       set i to (count characters of paragraphs 1 thru (targetParagraphNumber - 1)) + 1
       -- … then of the insertion point after any indentation at the beginning of the paragraph.
       repeat while (character i is in {tab, space})
           set i to i + 1
       end repeat
   end if
   -- Select the insertion point.
   set selection to insertion point i
end tell

-- Wiggle the cursor to bring it into view if it's not already.
tell application "System Events" to key code {124, 123}

Unfortunately, other applications require different code.

Edit: "Wiggle" added.

Last edited by Nigel Garvey (2017-12-05 08:01:18 am)


NG

Offline

 

#3 2017-12-05 12:38:50 pm

haolesurferdude
Member
Registered: 2010-02-19
Posts: 109

Re: Place Cursor at beginning of paragraph n

Here is one method for Microsoft Word.

Applescript:

tell application "Microsoft Word"
   activate
   set targetParagraphNumber to 12 as integer
   if targetParagraphNumber = 1 then
       set countValue to -1 as integer
   else
       set countValue to 1 as integer
   end if
   move range (text object of paragraph targetParagraphNumber of document 1) by a character item count countValue
end tell

Last edited by haolesurferdude (2017-12-05 12:39:15 pm)

Offline

 

#4 2017-12-05 05:30:40 pm

Joy
Member
From:: South Tirol
Registered: 2008-07-04
Posts: 542
Website

Re: Place Cursor at beginning of paragraph n

@Nigel Garvey
I did suspect the insertion point to be a helpful command, but just now I realized how it works. This outcome is  amazing!
I tested your code with a short script and everything worked like a charm.  Then I tried to apply my flavour and tested it on a longer script; paragraph 500. Of course tabs and spaces have a much higher numerical value than paragraph 500. Maybe grep could be faster to count tabs and spaces than a repeat handler (as AS Editor hung for long without too resolve), but I don't figure out how.

@haolesurferdude
Thanks very much for sharing! This command could apply very well with calc tables, I think

Offline

 

#5 2017-12-06 04:46:52 am

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

Re: Place Cursor at beginning of paragraph n

Joy wrote:

Of course tabs and spaces have a much higher numerical value than paragraph 500.


Hi Joy.

I'm afraid I don't understand that sentence. But what takes the time with a longer script document isn't the repeat — which only iterates across the indentation at the beginning of the target paragraph — but counting the characters of all the preceding paragraphs within the Script Editor document itself. It's faster to extract the contents as AppleScript text first and do the count in that:

Applescript:

-- Tested with SE 2.10 in 10.13.1.

set targetParagraphNumber to 422

delay 5 -- For testing only. Use the time to bring the target document to the front.

if (targetParagraphNumber is 1) then
   -- Use the index of the insertion point at the beginning of the text.
   set i to 1
else
   -- Get the contents of the document as AppleScript text.
   tell document 1 of application "Script Editor" to set txt to contents
   
   -- Get the index of the insertion point after the line ending before the target paragraph …
   set i to (count text 1 thru paragraph (targetParagraphNumber - 1) of txt) + 2
   -- … then of the insertion point after any indentation at the beginning of the paragraph.
   repeat while (character i of txt is in {tab, space})
       set i to i + 1
   end repeat
end if

-- Select the insertion point in the Script Editor document.
tell document 1 of application "Script Editor" to set selection to insertion point i

-- Wiggle the cursor to bring it into view if it's not already.
tell application "System Events" to key code {124, 123}


NG

Offline

 

#6 2017-12-06 10:03:04 am

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

Re: Place Cursor at beginning of paragraph n

Joy wrote:

Maybe grep could be faster ….


As an exercise, I've worked out a regex version. I don't think it's any better than the vanilla one immediately above, but it's interesting for a bug — er, "feature" — it's brought to light which affects Script Editor, Script Debugger, and ASObjC Explorer 4 in both High Sierra and El Capitan. Namely: if a script running in one of these editors contains a 'tell' statement addressed to the editor itself, any ASObjC code below that point isn't understood. For example, running this in Script Editor:

Applescript:

use AppleScript version "2.4"
use framework "Foundation"
use scripting additions

set str to current application's class "NSString"'s stringWithString:("Hello")
say (str as text) --> No problem.

tell application "Script Editor"
end tell

set str to current application's class "NSString"'s stringWithString:("Hello")
--> error "Script Editor got an error: class \"NSString\" doesn’t understand the “stringWithString_” message." number -1708 from class "NSString"

One way round this is to move anything the editor has to do before the ASObjC to a handler or handlers at the bottom of the script:

Applescript:

-- Tested with SE 2.10 in 10.13.1.

use AppleScript version "2.4"
use framework "Foundation"

set targetParagraphNumber to 422

delay 5 -- For testing only. Use the time to bring the target document to the front.

if (targetParagraphNumber is 1) then
   -- Use the index of the insertion point at the beginning of the text.
   set i to 1
else
   -- Use a handler below the main script to get the contents of the Script Editor document as AppleScript text …
   set txt to getDocumentContents()
   -- … then use ASObjC to convert it to an NSString.
   set str to current application's class "NSMutableString"'s stringWithString:(txt)
   
   -- Using a regex, reduce the NSString to everything in it up to the end of any indendation in the target paragraph.
   tell str to replaceOccurrencesOfString:("\\A((?:.*+\\R){" & targetParagraphNumber - 1 & "}[[:blank:]]*+).*+") withString:("$1") options:(current application's NSRegularExpressionSearch) range:({0, its |length|()})
   -- The length of its AS equivalent + 1 is the insertion point index we need.
   set i to (count (str as text)) + 1
end if

-- Select the insertion point in the Script Editor document.
tell document 1 of application "Script Editor" to set selection to insertion point i

-- Wiggle the cursor to bring it into view if it's not already.
tell application "System Events" to key code {124, 123}

on getDocumentContents()
   -- This is in a handler below the main code so that 'tell application "Script Editor"' isn't above the ASObjC code.
   tell document 1 of application "Script Editor" to return contents
end getDocumentContents


NG

Offline

 

#7 2017-12-07 06:31:08 am

Joy
Member
From:: South Tirol
Registered: 2008-07-04
Posts: 542
Website

Re: Place Cursor at beginning of paragraph n

cool
I tried all I know to get the "wiggle" lol working. Running the key code from within Script Editor does nothing, asistive devices are on and the Script Editor is authorized. My OS is 10.11

Applescript:

-- Wiggle the cursor to bring it into view if it's not already.
   delay 0.3
   try
       tell application "System Events" #to key code 124 #{124, 123}
           #tell process ASEditor #"Script Editor"
           key code 124 #{124, 123}
           key code 123 #{124, 123}
           #end tell
       end tell
   on error err
       activate
       display dialog err
   end try

Anyway the insertion point works wink

Offline

 

#8 2017-12-07 07:20:22 am

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 5200

Re: Place Cursor at beginning of paragraph n

Nigel Garvey wrote:

if a script running in one of these editors contains a 'tell' statement addressed to the editor itself, any ASObjC code below that point isn't understood.



It's a beauty, isn't it. My hand-waving theory is that the call to the editor makes it match current application, which then stops current application from doing its thing with ASObjC.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/

Offline

 

#9 2017-12-07 09:33:23 am

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

Re: Place Cursor at beginning of paragraph n

Joy wrote:

I tried all I know to get the "wiggle" lol working. Running the key code from within Script Editor does nothing, asistive devices are on and the Script Editor is authorized. My OS is 10.11


I'll look into it. It's not all that brilliant in 10.13 either.  wink  I'm finding that when a very long script's opened in Script Editor, it's not always possible to scroll to the bottom of it. Running the script above makes it possible, but doesn't actually do it first time.  roll


NG

Offline

 

#10 2017-12-07 09:52:28 am

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

Re: Place Cursor at beginning of paragraph n

Shane Stanley wrote:
Nigel Garvey wrote:

if a script running in one of these editors contains a 'tell' statement addressed to the editor itself, any ASObjC code below that point isn't understood.



It's a beauty, isn't it. My hand-waving theory is that the call to the editor makes it match current application, which then stops current application from doing its thing with ASObjC.


It looks to be something like that. In fact it's current application which isn't understood rather than ASObjC per se. Grabbing that first gets round the problem too:

Applescript:

use AppleScript version "2.4"
use framework "Foundation"
use scripting additions

set |⌘| to current application

set str to |⌘|'s class "NSString"'s stringWithString:("Hello")
say (str as text) --> No problem.

tell application "Script Editor"
end tell

set str to |⌘|'s class "NSString"'s stringWithString:("Hello")
say (str as text) --> No problem.


NG

Offline

 

#11 2017-12-07 04:31:02 pm

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

Re: Place Cursor at beginning of paragraph n

I wrote:
Joy wrote:

I tried all I know to get the "wiggle" lol working. Running the key code from within Script Editor does nothing, asistive devices are on and the Script Editor is authorized. My OS is 10.11


I'll look into it.


Hi Joy.

The wiggle does work on my macOS 10.11 machine, but isn't totally reliable. Script Editor has to be the frontmost app, of course, and the key codes (right arrow and left arrow) are applied to the frontmost window. If you happen to come across a more reliable way to make the window scroll to the cursor position, do let me know!  smile


NG

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)