Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/050-command-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -1357,6 +1357,14 @@ Add any of these commands to the workflow name to modify the workflow's entire b

- `#SmartBlock NameOfSmartBlock <%HIDE%>`

## CMD

**Purpose:** Opt the workflow into appearing in Roam's command palette when the Command Palette setting requires it

**Usage**

- `#SmartBlock NameOfSmartBlock <%CMD%>`

## NOCURSOR

**Purpose:** After a SmartBlock has finished running, Roam should be left in a non-edit state, meaning no block currently has editing focus
Expand Down
6 changes: 5 additions & 1 deletion docs/060-alternative-methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,12 @@ The input field in the configuration page is a special input field. It will reac

# Command Palette

You can surface all custom SmartBlock workflows to be triggered from the Roam Command Palette. To do so, head to the SmartBlocks Settings within RoamDepot, toggle on the command palette setting.
You can surface all custom SmartBlock workflows to be triggered from the Roam Command Palette. To do so, head to the SmartBlocks Settings within RoamDepot and toggle on the command palette setting. If you only want specific workflows to show up, enable the "Command Palette Opt-In" setting and add `<%CMD%>` to the workflow title you wish to expose.

![](media/command-palette.png)

Each workflow will start with a prefix `Trigger SmartBlock:` with the name of the workflow at the end of the command label.

## Refreshing Command Palette Workflows

After adding or removing the `<%CMD%>` tag from workflow titles (when Command Palette Opt-In is enabled), you may need to refresh the list of available workflows in the command palette. To do this, open the Roam Command Palette and search for "Refresh SmartBlocks Command Palette". Running this command will update the command palette with your current workflows and display a confirmation message.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "smartblocks",
"version": "1.11.1",
"version": "1.12.0",
"description": "Create custom and programmable templates from within Roam!",
"main": "./build/main.js",
"scripts": {
Expand Down
152 changes: 104 additions & 48 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,57 +115,76 @@ export default runExtension(async ({ extensionAPI }) => {
color: #4b5563;
}`);

const toggleCommandPalette = (flag: boolean) => {
const workflows = getCleanCustomWorkflows(getVisibleCustomWorkflows());
if (flag) {
workflows.forEach((wf) => {
window.roamAlphaAPI.ui.commandPalette.addCommand({
label: `Trigger SmartBlock: ${wf.name}`,
callback: () => {
const targetUid =
window.roamAlphaAPI.ui.getFocusedBlock()?.["block-uid"];
// Because the command palette does a blur event on close,
// we want a slight delay so that we could keep focus
window.setTimeout(() => {
if (targetUid) {
sbBomb({
srcUid: wf.uid,
target: {
uid: targetUid,
isParent: false,
start: getTextByBlockUid(targetUid).length,
},
mutableCursor: true,
});
} else {
window.roamAlphaAPI.ui.mainWindow
.getOpenPageOrBlockUid()
.then((uid) =>
sbBomb({
srcUid: wf.uid,
target: {
uid:
uid ||
window.roamAlphaAPI.util.dateToPageUid(new Date()),
isParent: true,
},
mutableCursor: true,
})
);
}
}, 500);
},
});
let commandPaletteEnabled = false;
let commandPaletteOptIn = !!extensionAPI.settings.get(
"command-palette-opt-in"
);

const removeCommandPaletteCommands = () => {
getCleanCustomWorkflows(getVisibleCustomWorkflows()).forEach((wf) => {
window.roamAlphaAPI.ui.commandPalette.removeCommand({
label: `Trigger SmartBlock: ${wf.name}`,
});
} else {
workflows.forEach((wf) => {
window.roamAlphaAPI.ui.commandPalette.removeCommand({
label: `Trigger SmartBlock: ${wf.name}`,
});
});
};

const addCommandPaletteCommands = () => {
const eligibleWorkflows = getVisibleCustomWorkflows().filter((wf) =>
commandPaletteOptIn ? wf.commandPaletteEligible : true
);
getCleanCustomWorkflows(eligibleWorkflows).forEach((wf) => {
window.roamAlphaAPI.ui.commandPalette.addCommand({
label: `Trigger SmartBlock: ${wf.name}`,
callback: () => {
const targetUid =
window.roamAlphaAPI.ui.getFocusedBlock()?.["block-uid"];
// Because the command palette does a blur event on close,
// we want a slight delay so that we could keep focus
window.setTimeout(() => {
if (targetUid) {
sbBomb({
srcUid: wf.uid,
target: {
uid: targetUid,
isParent: false,
start: getTextByBlockUid(targetUid).length,
},
mutableCursor: true,
});
} else {
window.roamAlphaAPI.ui.mainWindow
.getOpenPageOrBlockUid()
.then((uid) =>
sbBomb({
srcUid: wf.uid,
target: {
uid:
uid ||
window.roamAlphaAPI.util.dateToPageUid(new Date()),
isParent: true,
},
mutableCursor: true,
})
);
}
}, 500);
},
});
});
};

const syncCommandPaletteCommands = () => {
removeCommandPaletteCommands();
if (commandPaletteEnabled) {
addCommandPaletteCommands();
}
};

const toggleCommandPalette = (flag: boolean) => {
commandPaletteEnabled = flag;
syncCommandPaletteCommands();
};

let trigger = "jj";
let triggerRegex = /$^/;
const refreshTrigger = (value: string) => {
Expand Down Expand Up @@ -195,6 +214,19 @@ export default runExtension(async ({ extensionAPI }) => {
toggleCommandPalette((e.target as HTMLInputElement).checked),
},
},
{
id: "command-palette-opt-in",
name: "Command Palette Opt-In",
description:
"If enabled, workflows must include <%CMD%> in their title to appear in the command palette",
action: {
type: "switch",
onChange: (e) => {
commandPaletteOptIn = (e.target as HTMLInputElement).checked;
syncCommandPaletteCommands();
},
},
},
{
action: {
type: "input",
Expand Down Expand Up @@ -258,7 +290,8 @@ export default runExtension(async ({ extensionAPI }) => {
},
],
});
toggleCommandPalette(!!extensionAPI.settings.get("command-palette"));
commandPaletteEnabled = !!extensionAPI.settings.get("command-palette");
syncCommandPaletteCommands();
refreshTrigger(extensionAPI.settings.get("trigger") as string);

const customCommands: { text: string; help: string }[] = [];
Expand Down Expand Up @@ -397,6 +430,11 @@ export default runExtension(async ({ extensionAPI }) => {
id: "HIDE",
help: "Workflow modifier that hides this workflow from the standard SmartBlock menu execution",
},
{
text: "CMD",
id: "CMD",
help: "Workflow modifier that opts this workflow into appearing in the command palette when Command Palette Opt-In is enabled",
},
...customCommands.map(({ text, help }) => ({
text,
id: text,
Expand Down Expand Up @@ -514,6 +552,21 @@ export default runExtension(async ({ extensionAPI }) => {
},
});

const REFRESH_SMARTBLOCKS_COMMAND_LABEL =
"Refresh SmartBlocks Command Palette";
window.roamAlphaAPI.ui.commandPalette.addCommand({
label: REFRESH_SMARTBLOCKS_COMMAND_LABEL,
callback: () => {
syncCommandPaletteCommands();
renderToast({
id: "smartblocks-command-palette-refresh",
intent: Intent.SUCCESS,
content: "Command palette workflows refreshed",
timeout: 2000,
});
},
});

const logoObserver = createHTMLObserver({
className: "rm-page-ref--tag",
tag: "SPAN",
Expand Down Expand Up @@ -891,7 +944,10 @@ export default runExtension(async ({ extensionAPI }) => {
{ type: "input", listener: documentInputListener, el: document },
{ type: "keydown", listener: globalHotkeyListener, el: document },
],
commands: [RUN_MULTIPLE_SMARTBLOCKS_COMMAND_LABEL],
commands: [
RUN_MULTIPLE_SMARTBLOCKS_COMMAND_LABEL,
REFRESH_SMARTBLOCKS_COMMAND_LABEL,
],
unload: () => {
unloads.forEach((u) => u());
window.clearTimeout(getDailyConfig()["next-run-timeout"]);
Expand Down
20 changes: 15 additions & 5 deletions src/utils/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,9 @@ const predefinedChildrenByUid = Object.fromEntries(
);

export const HIDE_REGEX = /<%HIDE%>/i;
export const COMMAND_PALETTE_REGEX = /<%CMD%>/i;
const HIDE_REGEX_GLOBAL = /<%HIDE%>/gi;
const COMMAND_PALETTE_REGEX_GLOBAL = /<%CMD%>/gi;

const customWorkflowsCache: {
current?: { uid: string; name: string }[];
Expand Down Expand Up @@ -338,15 +341,22 @@ export const getCustomWorkflows = () => {
export const getVisibleCustomWorkflows = () =>
getCustomWorkflows()
.filter(({ name }) => !HIDE_REGEX.test(name))
.map(({ name, uid }) => ({
uid,
name: name.replace(HIDE_REGEX, ""),
}));
.map(({ name, uid }) => {
const commandPaletteEligible = COMMAND_PALETTE_REGEX.test(name);
return {
uid,
name: name
.replace(HIDE_REGEX_GLOBAL, "")
.replace(COMMAND_PALETTE_REGEX_GLOBAL, "")
.trim(),
commandPaletteEligible,
};
});

export const getCleanCustomWorkflows = (workflows = getCustomWorkflows()) =>
workflows.map(({ name, uid }) => ({
uid,
name: name.replace(/<%[A-Z]+%>/, "").trim(),
name: name.replace(/<%[A-Z]+%>/g, "").trim(),
}));

const getFormatter =
Expand Down
Loading