Reply to topic  [ 3 posts ] 
NWP macro and AppleScript interoperability? 
Author Message

Joined: 2014-07-12 03:21:50
Posts: 12
Hello,

I am trying to convert a short integration Applescript for BBEdit into a macro to make BBAutocomplete (http://c-command.com/bbautocomplete/) compatible with NWP. BBAutocomplete is good because it lets you cycle through completions by invoking BBAutocomplete again à la Emacs’ dabbrev-expand (M-/), which apparently is the inspiration for the program, until you get the right one.

A few problems: I need to convert an NWP-array to an AS-record and pass it to the script to be run from the macro, pass NWP-variables to the script and I need to be able to return an AS-variable from the script to an NWP-variable. Is this possible?

Of course I may also have look over some other detail that makes this whole thing not doable…

Regards,
Martin

Code:
$doc = Documents.active
if ! $doc
Prompt “No Document open!”
exit
end

# to be passed into the script that calls BBAutocomplete
$currentFileText = $doc.text

#Get start offset of word to be completed to be passed into the script that calls BBAutocomplete
Send Selector “moveWordBackwardAndModifySelection:”
$theOffset = $doc.activeSelection.range.location

# Fetch texts from open documents to be converted into an AS-record ‘alsoTexts’
$documentTexts = Array.new
foreach $d in Documents
   $documentTexts.push $d.text
end




# AppleScript parts.

# Convert array $documentTexts into AS-record $alsoTexts.
#
# AS-block copied from handler makeCompletion()
#
# Is this possible?
$AS = “
      tell application "BBAutoComplete"
         set theCompletion to complete word starting at offset $theOffset ¬
            in text $theCurrentFileText also using text $alsoTexts -- or some such thing
      end tell
      -- theCompletion is a record with three items: startOffset, endOffset and completionText 
                return third item of theCompletion“

$error = “”
$completionText = Run AppleScript $AS, $error

if defined $error
Prompt “AppleScript returned error: ” $error
Exit
End


#Replacement of handler applyCompletion().
$selectionRange = Range.new $thetOffset, $thetOffset + $doc.activeSelection.range.length
$doc.deleteInRange $selectionRange
$doc.insertAtIndex $theOffset, $completionText


BBEdit AppleScript:
Code:
(*
   BBEdit integration AppleScript to accompany
    BBAutoComplete <http://c-command.com/bbautocomplete>.
    Copyright © 2002-2012 Michael Tsai, <bbautocomplete@c-command.com>.

   Put this script in BBEdit's Scripts folder.
*)

on canCompleteInWindow(w)
   tell application "BBEdit"
      return class of w is in {shell window, text window, disk browser window, project window, search results browser}
   end tell
end canCompleteInWindow

on windowHasSingleText(w)
   tell application "BBEdit"
      return class of w is in {shell window, disk browser window, results browser, search results browser}
   end tell
end windowHasSingleText

on windowHasMultipleTexts(w)
   tell application "BBEdit"
      return class of w is in {text window, project window}
   end tell
end windowHasMultipleTexts

on makeAlsoTexts()
   tell application "BBEdit"
      set theResult to {}
      -- this will include the first document from window 1, but that's OK
      repeat with w in windows
         if my windowHasSingleText(w) then
            try
               copy text of w to end of theResult
            end try
         else if my windowHasMultipleTexts(w) then
            repeat with d in text documents of w
               copy text of d to end of theResult
            end repeat
         else
            --log "Skipping: " & (name of w)
         end if
      end repeat
      return theResult
   end tell
end makeAlsoTexts

on makeCompletion()
   tell application "BBEdit"
      set theCurrentFileText to contents of window 1
      set theOffset to characterOffset of selection
      set alsoTexts to my makeAlsoTexts()
      tell application "BBAutoComplete"
         set theCompletion to complete word starting at offset theOffset ¬
            in text theCurrentFileText also using text alsoTexts
      end tell
      return theCompletion
   end tell
end makeCompletion

on applyCompletion(c)
   set {startOffset, endOffset, completionText} to c
   tell application "BBEdit"
      if startOffset is not equal to endOffset then
         select characters (startOffset + 1) thru endOffset of window 1
      else
         try
            select insertion point after character endOffset of window 1
         end try
      end if
      set selection to completionText
      if the length of the selection is greater than 0 then
         select insertion point after selection
      end if
   end tell
end applyCompletion

on run
   tell application "BBEdit"
      if my canCompleteInWindow(window 1) then
         my applyCompletion(my makeCompletion())
      else
         display dialog "Completion doesn’t work when the front window is of type “" & class of window 1 & "”." buttons {"OK"} default button "OK"
      end if
   end tell
end run


2014-07-29 12:43:11
Profile

Joined: 2008-03-16 16:41:16
Posts: 20
Well, since you’re creating the AppleScript within the Nisus macro, you can pass the Nisus array to AppleScript simply by creating it on the fly in your AppleScript string.

For the return trip, Nisus gets back the last value generated by the AppleScript as a string. As far as I can tell, it’s the same text that you get in the “results” pane inside AppleScript Editor.

Here’s a simple example of converting a Nisus hash into an AppleScript record, using it, and then getting back the string:

Code:
$greetingData = Hash.new(‘greeting’, ‘hello’)
$greetingData{‘nickname’} = ‘fred’

$greetingGetter = “set greeting to {“

$comma = “ ”
ForEach $key, $value in $greetingData
   $greetingGetter &= “$comma$key: \"$value\"“
   
   $comma = “, ”
End

$greetingGetter &= “}\n”
$greetingGetter &= “get greeting of greeting & space & nickname of greeting”
prompt $greetingGetter

$error = “”
$greeting = Run AppleScript $greetingGetter, $error


if $greeting
   prompt $greeting
end

if $error
   prompt $error
end


Note that if you need a hash or array back, you’ll need to use something like .split on the returned string value to convert it from a string into an array. Something like:

Code:
$greetingData = Hash.new(‘greeting’, ‘hello’)
$greetingData{‘nickname’} = ‘fred’

$greetingGetter = “set greeting to {“

$comma = “ ”
ForEach $key, $value in $greetingData
   $greetingGetter &= “$comma$key: \"$value\"“
   
   $comma = “, ”
End

$greetingGetter &= “}\n”
$greetingGetter &= “set response to {greeting: greeting of greeting & space & nickname of greeting, success:\"yes\"}”
prompt $greetingGetter

$error = “”
$greeting = Run AppleScript $greetingGetter, $error

$greeting = $greeting.split(‘,’)
$response = Hash.new()
foreach $keyvalue in $greeting
   $key, $value = $keyvalue.split(‘:’)
   $response{$key} = $value
end

if $greeting
   prompt $response
end

if $error
   prompt $error
end

_________________
Mimsy Were the Borogoves


2014-07-29 14:38:41
Profile WWW

Joined: 2014-07-12 03:21:50
Posts: 12
capvideo wrote:
Well, since you’re creating the AppleScript within the Nisus macro, you can pass the Nisus array to AppleScript simply by creating it on the fly in your AppleScript string.

For the return trip, Nisus gets back the last value generated by the AppleScript as a string. As far as I can tell, it’s the same text that you get in the “results” pane inside AppleScript Editor.

Thanks! That works well .

This thing does seem to be possible to do . One or two details left to fix.

Regards,
Martin


2014-07-30 01:53:49
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 3 posts ] 

Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software