Thanks @saf-dmitry for the original script and @Jim for the tweaks. Two questions:
I too created a KM macro to run this one for me, but with both running the script from KM and Script Editor, after execution (or during) it brings Taskpaper to the foreground - any idea on how to have this quick entry in the background?
Do either of you know how to get this working with a KM variable for the path? I’d like to add some logic for changing the path based on work or home taskpaper lists and then pass the path variable to the script. I stole the following from @complexpoint’s script, but I kept on getting an “The document “Test.taskpaper” could not be opened. The file doesn’t exist.” error from Taskpaper that the file was not found, even though the file and path are correct.
var kmVars = Application("Keyboard Maestro Engine")
.variables;
var filePath = kmVars.pathVariable.value(); // Path to TaskPaper file
...
I can’t remember if the Keyboard Maestro osascript interface changed at any point, but the usual way to read a value for a KM variable name would be with:
Odd. When I run it from Keyboard Maestro, TaskPaper stays in the background.
Here is the version of the script that I am running, on the chance that it helps:
var filePath = "~/Library/Mobile Documents/iCloud~is~workflow~my~workflows/Documents/Focus.txt"; // Path to TaskPaper file
var appendItems = true; // If true, items will be added to the end rather than top of Inbox
function TaskPaperContextScript(editor, options) {
var outline = editor.outline;
var inbox = outline.evaluateItemPath("//@type=project and @text matches[s] ^Inbox:")[0];
var items;
if (options.text && options.text !== "") {
items = ItemSerializer.deserializeItems(options.text, outline, ItemSerializer.TEXTMimeType);
}
if (!inbox) {
inbox = outline.createItem("Inbox:");
outline.root.insertChildrenBefore(inbox, outline.root.firstChild);
}
if (items) {
if (options.append) {
inbox.appendChildren(items);
} else {
inbox.insertChildrenBefore(items, inbox.firstChild);
}
}
}
var app = Application("System Events");
app.includeStandardAdditions = true;
var prompt = app.displayDialog("Capture what has your attention:", {
withTitle: "Ubiquitous Capture Tool",
withIcon: Path("/Users/jim/—ƒ—/Icons/TaskPaper3.icns"),
buttons: ["Cancel", "Capture"],
defaultAnswer: "",
defaultButton: "Capture"
})
var tp3 = Application("TaskPaper");
var strFullPath = ObjC.unwrap($(filePath).stringByExpandingTildeInPath);
var document = tp3.open(Path(strFullPath));
document.evaluate({
script: TaskPaperContextScript.toString(),
withOptions: {text: ("- " + prompt.textReturned), append: appendItems}
});
document.save();
Hey @complexpoint thanks for the help, although I get the same error as before. Not sure what the issue is there. Perhaps it’s elsewhere in the script then
Thanks @Jim. So what I actually noticed with mine is that it doesn’t bring it to the front per se, but rather if taskpaper is minimised it’ll unminimise it and then which back to whatever app you were working in.
Not sure if this is the same behaviour for you and your script (haven’t had a chance to try it yet), but either way an easy fix for me is to keep Taskpaper in full screen in another desktop
@saf-dmitry I don’t know if you are still following this thread but i’m struggling to get the script to work in alfred. I know little about scripting but i’ve updated the path in the script but i when i run the debugger in alfred i get this error. Any help would be appreciated:
[10:30:55.044] TaskPaper[Keyword] Processing complete
[10:30:55.045] TaskPaper[Keyword] Passing output ‘test’ to Run Script
[10:30:55.109] ERROR: TaskPaper[Run Script] execution error: Error: Error: exception raised by object: *** +[NSString stringWithUTF8String:]: NULL cString (-2700)
You don’t need to update anything “in the script”, but you have to set the file_path workflow environment variable. It shoud be something like ~/tasks.taskpaper.
I managed to get this working with alfred after all – not sure what i did wrong. Anyway – just curious – would it be possible to do this without opening the file at all?
You probably can read the file as UTF-8-encoded file, deserialize its content using ItemSerializer.deserializeItems, add new items, serialize the outline using ItemSerializer.serializeItems and write it back as UTF-8-encoded file under the same name.