Applescript for setting context

It would be convenient to have an Applescript that simply sets a specific context for the selected task. This is probably easy to do, but my Applescript knowledge is unfortunately still very limited, so maybe someone could tell me what the script should look like.

You could do this with AppleScript, but it would probably be less work for you to select the task and then type the first few characters of the context in the inspector in the right sidebar. You can do this with multiple tasks selected, too.

The reason that I would like to have an Applescript for it is that I have some contexts I use very often. I would find it convenient to create separate Applescripts for those and then assign each Applescript to a separate keyboard command. I have done that for deferring tasks specified numbers of days, and I’m happy with how that works.

Try Keyboard Maestro for this! It is very easy to configure without any programming knowledge! You can for example assign a shortcut that types the tab button and then enters your context name ant then simulates e.g. another keystroke (tab,return,…).

1 Like

Has anyone created this? Or does anybody know if this script can be found anywhere?

Also, does anybody know about an applescript for setting project as well?

This is a script I made. Maybe it helps.
It sets a specific context to the currently selected tasks.

Code:

-- unlocked2412
-- This script sets a specific context to the currently selected tasks.

property the_context_name : "" -- CHANGE THIS PROPERTY VALUE TO REFLECT YOU DESIRED CONTEXT

tell application "OmniFocus"
	set o_doc to front document
	tell o_doc
		set the_context_value to first flattened context whose (name = the_context_name)
	end tell
	set o_win to front document window of front document
	tell o_win
		tell content
			set lst_tasks to value of selected trees
			if lst_tasks ≠ {} then
				repeat with i in lst_tasks
					set the_task to contents of i
					set context of the_task to the_context_value
				end repeat
			else
				display dialog "Select one or more tasks, please."
			end if
		end tell
	end tell
end tell
2 Likes

This script sets a specific project to the currently selected tasks.

Code:

-- unlocked2412
-- This script sets a specific project to the currently selected tasks.

property the_project_name : "" -- CHANGE THIS PROPERTY VALUE TO REFLECT YOU DESIRED PROJECT

tell application "OmniFocus"
	set o_doc to front document
	tell o_doc
		set the_project_value to first flattened project whose (name = the_project_name)
	end tell
	set o_win to front document window of front document
	tell o_win
		tell content
			set lst_tasks to value of selected trees
			if lst_tasks ≠ {} then
				repeat with i in lst_tasks
					set the_task to contents of i
					move the_task to end of tasks of the_project_value
				end repeat
			else
				display dialog "Select one task, please"
			end if
		end tell
	end tell
end tell
2 Likes

I had the same issue. In my case there are tasks which, for one reason or another, cannot be performed because they were overtaken by events or no longer became relevant. I don’t want to delete them: they were present in previous reports and therefore need to be accounted. Also, contexts which have the status “Dropped” do not show up in the standard Context dropdown (to answer one of the questions below).

unlocked2412 script is great! I like this one because a) I wrote it 😀 and b) it completes the task at the same time. Let me know what you think!

property DesiredContextName : "Abandoned"

tell application "OmniFocus"
	-- Lookup the context we want
	tell front document
		try
			set DesiredContext to (first flattened context where name is DesiredContextName)
		on error line number -1719
			display alert "Can't find \"" & DesiredContextName & "\" context" as critical
			return
		end try
		set newContext to DesiredContext
		-- With the new context in hand apply it to the selected tasks		
		tell content of first document window --of the front document (we're nestled)
			--Get selection - exclude everything that isn't a task
			set validSelectedItemsList to value of (selected trees where class of its value is not item and class of its value is not folder and class of its value is not context and class of its value is not perspective)
			set totalItems to count of validSelectedItemsList
			if totalItems is 0 then
				display alert "No valid task(s) selected" as critical
				return
			end if
			repeat with thisItem in validSelectedItemsList
				set context of thisItem to newContext
				set completed of thisItem to true
			end repeat
		end tell
	end tell
end tell

Hi All,

I am adding to this topic as I have a question on a similar problem
I want to delete the context of projects and tasks that are completed and assign it another specific context.
calling every flattened task of a specific project and using “delete context of” on tasks worked.

but when I moved to this

tell application “OmniFocus”
set target_context to first flattened context whose (name = “batch closed”)
tell default document
set ProjectList to every flattened project whose name is “test project”
repeat with P in ProjectList
if P is completed then
delete context of P
set context of P to target_context
end if
set tasklist to every flattened task of P
repeat with T in tasklist
if T is completed then
delete context of T
set context of T to target_context
end if
end repeat
end repeat
end tell
end tell

OF2 crashed and deleted all contexts from everything forcing me to revert a backup.
Has anyone already implemented a similar script?

thanks,
S

If I understand correctly, you need to delete (from your OF database) every context from items that matches this conditions:

  • Projects:
    • Name = “test project”
    • Completed = true
  • Tasks:
    • Tasks that belong to a project whose (name = “test project”)
    • Completed = true

First, you need to target a specific OF document to retrieve first flattened context.... I couldn’t run your code because of it.
Code:

tell application "OmniFocus"
	tell default document
		set target_context to first flattened context whose (name = "batch closed")
	end tell
end tell

Maybe this works.
Code:

-- unlocked2412
tell application "OmniFocus"
	tell default document
		set target_context to first flattened context whose (name = "batch closed")
		set lstProjects to (every flattened project whose (name = "test project") and (completed = true))
		
		repeat with i from 1 to (count lstProjects)
			set refProject to item i of lstProjects
			if (context of refProject) ≠ missing value then
				delete context of refProject
			end if
			set context of refProject to target_context
			set lstTasks to (every flattened task of refProject whose (completed is true))
			repeat with x from 1 to (count lstTasks)
				set refTask to item x of lstTasks
				if (context of refTask) ≠ missing value then
					delete context of refTask
				end if
				set context of refTask to target_context
			end repeat
		end repeat
	end tell
end tell

P.S.: When you loop though a reference, e.g.:

set tasklist to every flattened task of P
repeat with T in tasklist

Applescript assigns T to item 1 of {task id "kd2C6Nc5vnZ" ...} instead of fetching the actual object. So, you need to ask for the contents property of the loop variable, as in:

set tasklist to every flattened task of P
repeat with T in tasklist
    set refTask to (contents of T)
1 Like

Quick update: in OmniFocus version 2.12.1 {ahem} Omni changed the way AppleScript handles completing tasks. The script below traps for that and, if it finds a new version, applies the new method.

 property DesiredContextName : "Abandoned"

tell application "OmniFocus"
	set buildVersion to (build number as real) -- Need to know version as completion method has changed
	-- Lookup the context we want
	tell front document
		try
			set DesiredContext to (first flattened context where name is DesiredContextName)
		on error line number -1719
			display alert "Can't find \"" & DesiredContextName & "\" context" as critical
			return
		end try
		set newContext to DesiredContext
		-- With the new context in hand apply it to the selected tasks		
		tell content of first document window --of the front document (we're nestled)
			--Get selection - exclude everything that isn't a task
			set validSelectedItemsList to value of (selected trees where class of its value is not item and class of its value is not folder and class of its value is not context and class of its value is not perspective)
			set totalItems to count of validSelectedItemsList
			if totalItems is 0 then
				display alert "No valid task(s) selected" as critical
				return
			end if
			repeat with thisItem in validSelectedItemsList
				set context of thisItem to newContext
				if buildVersion < 113.39 then
					set completed of thisItem to true
				else
					mark complete thisItem
				end if
			end repeat
		end tell
	end tell
end tell

😀