How to control the filename of Applescripts embedded as an action

This may be a very simple problem, as I am a beginner in scripting.

I’m experimenting with Omnifocus, a to-do list app. It doesn’t come with a tagging system, but NickHibma has released an AppleScript that does just this. It’s actually two scpt files: label.scrpt and OmniFocusLib.script. I’ve pasted the entire script below for reference. The way it works is that you make copies of label.scpt, and change the names to your desired tags (work.scpt, home.scpt, etc.).

I’ve tried it from Script Editor and it works, but from embedding the script in a KM macro it does not. Rather I am getting tags with the format “Keyboard-Maestro-Script-85B64ACB-4E29-4D8E-B269-2AD6E531902A” with random numbers and letters.

Can anyone shed a little light on what is going on here? If the scripts below did not come out easy to read, please click here to download the originals.

label.scrpt

set theLib to POSIX path of (path to home folder) & "Library/Application Scripts/com.omnigroup.OmniFocus2/OmniFocusLib.scpt"
set OmniFocusLib to (load script POSIX file theLib)

tell OmniFocusLib
   toggleLabel(scriptName(), 2)
end tell

OmniFocusLib.scpt

-- Parts based on a script, copyright © 2010 Dan Byler (contact: dbyler@gmail.com), http://www.opensource.org/licenses/mit-license.php
--
-- "If it breaks, you get to keep the pieces."

on strreplace_all(str, substr)
   -- Replace all occurrences of substr in str.
   
   repeat
      set o to offset of substr in str
      if o is equal to 0 then exit repeat
      
      if o is 1 then
         set str_pre to ""
      else
         set str_pre to text 1 thru (o - 1) of str
      end if
      if o + (length of substr) is length of str then
         set str_post to ""
      else
         set str_post to text (o + (length of substr)) thru -1 of str
      end if
      set str to str_pre & str_post
   end repeat
   return str
end strreplace_all

on chip(str, substr)
   -- Remove a prefix from a string if present.
   
   try
      set o to (length of substr) + 1
      if text 1 thru (o - 1) of str is substr then
         return characters o thru -1 of str as string
      end if
   end try
   return str
end chip

on chop(str, substr)
   -- Remove a postfix from a string if present.
   
   try
      set o to (length of str) - (length of substr) + 1
      if text o thru (length of str) of str is substr then
         return characters 1 thru (o - 1) of str as string
      end if
   end try
   return str
end chop

on removeExtension(filename)
   -- Remove the extension (.<bla>) from the tail of the filename.
   
   set i to length of filename
   repeat while i is greater than 0
      if character i of filename is "." then
         return characters 1 thru (i - 1) of filename as string
      end if
      set i to i - 1
   end repeat
   return filename
end removeExtension

on fileBasename(filename)
   -- Remove everything up to and including the last '/'. If no '/' is
   -- present, the filename is returned as is.
   --
   -- Note: This assumes a POSIX file name.
   
   set i to length of filename
   repeat while i is greater than 0
      if character i of filename is "/" then
         return characters (i + 1) thru -1 of filename as string
      end if
      set i to i - 1
   end repeat
   return filename
end fileBasename

on fileDirname(filename)
   -- Remove everything from and including the last '/' onwards (the 'basename). If no '/' if found '.' is returned to indicate the current directory.
   -- '', '/' indicates the root dir.
   --
   -- Note: This assumes a POSIX file name.
   
   set i to length of filename
   repeat while i is greater than 0
      if character i of filename is "/" then
         if i is greater than 0 then
            return characters 1 thru (i - 1) of filename as string
         else
            return "/"
         end if
      end if
      set i to i - 1
   end repeat
   return "."
end fileDirname

on scriptName()
   -- Determine name of AppleScript file and chop off .scpt extension.
   
   tell application "Finder" to set filename to name of file (path to me) as text
   return removeExtension(fileBasename(filename))
end scriptName

on addLabel(selectedItem, label)
   -- Add "{<label>}" to the beginning of the title of the selected action(s).
   
   try
      if name of selectedItem does not contain label then
         set name of selectedItem to label & name of selectedItem
         return true
      end if
   end try
   return false
end addLabel

on removeLabel(selectedItem, label)
   -- Remove "{<label>}" from anywhere in the title of the selected action(s).
   
   set theName to name of selectedItem
   set theName2 to strreplace_all(theName, label)
   if theName is not equal to theName2 then
      set name of selectedItem to theName2
      return true
   else
      return false
   end if
end removeLabel

on removeAllLabels(selectedItem)
   -- Remove all labels like "{...} " from the title of an action
   
   set theName to name of selectedItem
   set theName2 to theName
   repeat
      set ob to offset of "{" in theName
      if ob is 0 then exit repeat
      set oe to (offset of "} " in (text ob thru -1 of theName)) + ob - 1
      if oe is ob then exit repeat
      
      if ob is not 1 and oe is not length of theName then
         set theName to (text 1 thru (ob - 1) of theName) & (text (oe + 2) thru -1 of theName)
      else if ob is not 1 then
         set theName to text 1 thru (ob - 1) of theName
      else
         set theName to text (oe + 2) thru -1 of theName
      end if
   end repeat
   
   if theName is not equal to theName2 then
      set name of selectedItem to theName
      return true
   else
      return false
   end if
end removeAllLabels

on toggleLabel(label, doNotifications)
   -- Add or remove a label from selected actions. If there is at least one action
   -- without the label, add the label to the actions that don't have it. Otherwise
   -- remove the label from all actions. If the label is "-" all labels removed.
   --
   -- label -- label to add or remove (added as "{<label>} "; note the trailing space!), or "-"
   -- doNotifications - 0 no notifications, 1 notify if problem or more than 1 item selected, 2 notify in all cases
   
   tell application "OmniFocus"
      activate
      tell content of first document window of front document
         set validSelectedItemsList to value of (selected trees where class of its value is not folder)
         
         set doAddLabel to false
         if label is "-" then
            set action to "cleaned"
         else
            set action to "unmarked as " & label
            repeat with selectedItem in validSelectedItemsList
               try
                  if name of selectedItem does not contain label then
                     set action to "marked as " & label
                     set doAddLabel to true
                  end if
               end try
            end repeat
         end if
         
         set changedItems to 0
         repeat with selectedItem in validSelectedItemsList
            if label is "-" then
               if my removeAllLabels(selectedItem) then set changedItems to changedItems + 1
            else if doAddLabel then
               if my addLabel(selectedItem, "{" & label & "} ") then set changedItems to changedItems + 1
            else
               if my removeLabel(selectedItem, "{" & label & "} ") then set changedItems to changedItems + 1
            end if
         end repeat
         
         set autosave to true
         
         set totalItems to count of validSelectedItemsList
         if totalItems is 0 then
            if doNotifications is greater than or equal to 1 then
               display notification "No valid tasks selected" with title "OmniFocus" subtitle "Marking failed"
            end if
            return true
         else
            if doNotifications is 2 or (doNotifications is 1 and totalItems is greater than 1) then
               if totalItems is greater than 1 and changedItems is not equal to totalItems then
                  set changedItems to changedItems & " of " & totalItems & " items"
               else if changedItems is 1 then
                  set changedItems to "1 item"
               else
                  set changedItems to changedItems & " items"
               end if
               
               display notification changedItems & " " & action & "." as string with title "OmniFocus" subtitle "Actions " & action
               return true
            end if
         end if
      end tell
   end tell
end toggleLabel

Hey Matt,

These are designed to run as script files saved somewhere in the Finder.

label.scrpt is the main script.

OmniFocusLib.scpt is a library script called by the main script.

The scriptName() handler calls path to me which requires that there be a me (a file).

When you run that as a text script from Keyboard Maestro it picks up the temp-file Keyboard Maestro is running it from.

Why someone has set the label to the name of the calling script I do not know.

Note that Keyboard Maestro’s Execute an AppleScript action can run a script-file or a text-script.

Script files should be saved from the Script Editor.app.

My demo of OmniFocus is expired, so I won’t look into this further.

-Chris

Thank you ccstone, knowing this I solved the problem! Works perfectly.

Check it out:

1 Like