Skip to content

Commit

Permalink
Merge pull request #722 from Ovyerus/feat/add-uri
Browse files Browse the repository at this point in the history
Add URI to run QuickAdd externally
  • Loading branch information
chhoumann authored Mar 5, 2025
2 parents b7df61e + bfcd85f commit 5f2ca2e
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 6 deletions.
29 changes: 29 additions & 0 deletions docs/docs/Advanced/ObsidianUri.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
title: Open QuickAdd from a URI
---

QuickAdd choices can be launched from external scripts or apps such as Shortcuts on Mac and iOS, through the use of the `obsidian://quickadd` URI.

```
obsidian://quickadd?choice=<YOUR_CHOICE_NAME>[&value-VALUE_NAME=...]
```

:::note

All parameter names and values must be properly [URL encoded](https://en.wikipedia.org/wiki/Percent-encoding) to work. You can use an online tool like [urlencoder.org](https://www.urlencoder.org/) to help you easily encode parts of the URI.

:::

The only required parameter is `choice` which selects the choice to run by its name. The name must match exactly, otherwise it will not be able to be found.

[Variables to your choice](../FormatSyntax.md) are passed as additional `value-VARIABLE_NAME` parameters, with `value-` prefixing the name. Variables with a space in their name can still be used, but the spaces in the name must be encoded as `%20` as usual. For example, a capture asking for a variable named `log notes` would be passed as `value-log%20notes=...` in the URI.

Keep in mind that unnamed variables (a bare `{{VALUE}}`/`{{NAME}}` or `{{MVALUE}}`) cannot be filled by the URI and you will instead be prompted inside Obsidian as usual.

## Vault parameter

Like every Obsidian URI, you can use the special `vault` parameter to specify which vault to run QuickAdd in. If left blank, it will be executed in your most recent vault.

```
obsidian://quickadd?vault=My%20Vault&choice=Daily%20log&value-contents=Lorem%20ipsum.
```
4 changes: 2 additions & 2 deletions docs/docs/FormatSyntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ title: Format syntax
| `{{VALUE}}` or `{{NAME}}` | Interchangeable. Represents the value given in an input prompt. If text is selected in the current editor, it will be used as the value. |
| `{{VALUE:<variable name>}}` | You can now use variable names in values. They'll get saved and inserted just like values, but the difference is that you can have as many of them as you want. Use comma separation to get a suggester rather than a prompt. |
| `{{LINKCURRENT}}` | A link to the file from which the template is activated from. `[[link]]` format. |
| `{{MACRO:<MACRONAME>}}` | Execute a macro and get the write the return value here. |
| `{{MACRO:<MACRONAME>}}` | Execute a macro and write the return value here. |
| `{{TEMPLATE:<TEMPLATEPATH>}}` | Include templates in your `format`. Supports Templater syntax. |
| `{{MVALUE}}` | Math modal for writing LaTeX. Use CTRL + Enter to submit. |
| `{{FIELD:<FIELDNAME>}}` | Suggest the values of `FIELDNAME` anywhere `{{FIELD:FIELDNAME}}` is used. Fields are YAML fields, and the values represent any value this field has in your vault. If there exists no such field or value, you are instead prompted to enter one. This is currently in beta, and the syntax can change—leave your thoughts [here](https://github.com/chhoumann/quickadd/issues/337). |
| `{{selected}}` | The selected text in the current editor. Will be empty if no active editor exists. |
| `{{selected}}` | The selected text in the current editor. Will be empty if no active editor exists. |
10 changes: 7 additions & 3 deletions docs/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ const sidebars = {
],
},
"FormatSyntax",
'InlineScripts',
'AIAssistant',
"InlineScripts",
"AIAssistant",
{
type: "category",
label: "Examples",
Expand All @@ -57,7 +57,11 @@ const sidebars = {
{
type: "category",
label: "Advanced",
items: ["QuickAddAPI", "Advanced/scriptsWithSettings"],
items: [
"QuickAddAPI",
"Advanced/scriptsWithSettings",
"Advanced/ObsidianUri",
],
},
{
type: "category",
Expand Down
41 changes: 40 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,18 @@ import { UpdateModal } from "./gui/UpdateModal/UpdateModal";
import { CommandType } from "./types/macros/CommandType";
import { InfiniteAIAssistantCommandSettingsModal } from "./gui/MacroGUIs/AIAssistantInfiniteCommandSettingsModal";

// Parameters prefixed with `value-` get used as named values for the executed choice
type CaptureValueParameters = { [key in `value-${string}`]?: string };

interface DefinedUriParameters {
choice?: string; // Name
}

type UriParameters = DefinedUriParameters & CaptureValueParameters;

export default class QuickAdd extends Plugin {
static instance: QuickAdd;
settings: QuickAddSettings;

private unsubscribeSettingsStore: () => void;

get api(): ReturnType<typeof QuickAddApi.GetApi> {
Expand Down Expand Up @@ -91,6 +99,37 @@ export default class QuickAdd extends Plugin {
},
});

this.registerObsidianProtocolHandler("quickadd", async (e) => {
const parameters = e as unknown as UriParameters;
if (!parameters.choice) {
log.logWarning(
"URI was executed without a `choice` parameter."
);
return;
}
const choice = this.getChoice("name", parameters.choice);

if (!choice) {
log.logError(
`URI could not find any choice named '${parameters.choice}'`
);
return;
}

const choiceExecutor = new ChoiceExecutor(this.app, this);
Object.entries(parameters)
.filter(([key]) => key.startsWith("value-"))
.forEach(([key, value]) => {
choiceExecutor.variables.set(key.slice(6), value);
});

try {
await choiceExecutor.execute(choice);
} catch (err) {
log.logError(err as string);
}
});

log.register(new ConsoleErrorLogger()).register(new GuiLogger(this));

if (this.settings.enableRibbonIcon) {
Expand Down

0 comments on commit 5f2ca2e

Please sign in to comment.