mirror of
https://github.com/foambubble/foam.git
synced 2026-04-24 03:01:01 -04:00
[Templates v2] Add FOAM_TITLE snippet variable (#549)
* Remove unused variables to appease the linter * Remove unecessary escape character To appease the linter * Add FOAM_TITLE snippet variable
This commit is contained in:
committed by
GitHub
parent
531bdab250
commit
b1bdf766b1
@@ -14,4 +14,14 @@ To create a note from a template, execute the `Foam: Create New Note From Templa
|
||||
|
||||
_Theme: Ayu Light_
|
||||
|
||||
### Variables
|
||||
|
||||
Templates can use all the variables available in [VS Code Snippets](https://code.visualstudio.com/docs/editor/userdefinedsnippets#_variables).
|
||||
|
||||
In addition, you can also use variables provided by Foam:
|
||||
|
||||
| Name | Description |
|
||||
| ------------ | ----------------------------------------------------------------------------------- |
|
||||
| `FOAM_TITLE` | The title of the note. If used, Foam will prompt you to enter a title for the note. |
|
||||
|
||||
**Note:** neither the defaulting feature (eg. `${variable:default}`) nor the format feature (eg. `${variable/(.*)/${1:/upcase}/}`) (available to other variables) are available for these Foam-provided variables.
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import { window } from 'vscode';
|
||||
import { substituteFoamVariables } from './create-from-template';
|
||||
|
||||
describe('substituteFoamVariables', () => {
|
||||
test('Does nothing if no Foam-specific variables are used', async () => {
|
||||
const input = `
|
||||
# \${AnotherVariable} <-- Unrelated to foam
|
||||
# \${AnotherVariable:default_value} <-- Unrelated to foam
|
||||
# \${AnotherVariable:default_value/(.*)/\${1:/upcase}/}} <-- Unrelated to foam
|
||||
# $AnotherVariable} <-- Unrelated to foam
|
||||
# #CURRENT_YEAR-\${CURRENT_MONTH}-$CURRENT_DAY <-- Unrelated to foam
|
||||
`;
|
||||
|
||||
expect(await substituteFoamVariables(input)).toEqual(input);
|
||||
});
|
||||
|
||||
test('Resolves FOAM_TITLE', async () => {
|
||||
const input = `
|
||||
# $FOAM_TITLE <-- The title goes here
|
||||
# \${FOAM_TITLE} <-- and also here
|
||||
`;
|
||||
|
||||
const foam_title = 'My note title';
|
||||
|
||||
jest
|
||||
.spyOn(window, 'showInputBox')
|
||||
.mockImplementationOnce(jest.fn(() => Promise.resolve(foam_title)));
|
||||
|
||||
const expected = `
|
||||
# My note title <-- The title goes here
|
||||
# My note title <-- and also here
|
||||
`;
|
||||
|
||||
expect(await substituteFoamVariables(input)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
@@ -23,7 +23,7 @@ Welcome to Foam templates.
|
||||
|
||||
What you see in the heading is a placeholder
|
||||
- it allows you to quickly move through positions of the new note by pressing TAB, e.g. to easily fill fields
|
||||
- a placeholder optionally has a default value, which can be some text or, as in this case, a [variables](https://code.visualstudio.com/docs/editor/userdefinedsnippets#_variables)
|
||||
- a placeholder optionally has a default value, which can be some text or, as in this case, a [variable](https://code.visualstudio.com/docs/editor/userdefinedsnippets#_variables)
|
||||
- when landing on a placeholder, the default value is already selected so you can easily replace it
|
||||
- a placeholder can define a list of values, e.g.: \${2|one,two,three|}
|
||||
- you can use variables even outside of placeholders, here is today's date: \${CURRENT_YEAR}/\${CURRENT_MONTH}/\${CURRENT_DATE}
|
||||
@@ -52,6 +52,58 @@ async function offerToCreateTemplate(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
function findFoamVariables(templateText: string): string[] {
|
||||
const regex = /\$(FOAM_[_a-zA-Z0-9]*)|\${(FOAM_[[_a-zA-Z0-9]*)}/g;
|
||||
var matches = [];
|
||||
const output: string[] = [];
|
||||
while ((matches = regex.exec(templateText))) {
|
||||
output.push(matches[1] || matches[2]);
|
||||
}
|
||||
const uniqVariables = [...new Set(output)];
|
||||
return uniqVariables;
|
||||
}
|
||||
|
||||
function getFoamTitle() {
|
||||
return window.showInputBox({
|
||||
prompt: `Enter a title for the new note`,
|
||||
value: 'Title of my New Note',
|
||||
validateInput: value =>
|
||||
value.trim().length === 0 ? 'Please enter a title' : undefined,
|
||||
});
|
||||
}
|
||||
|
||||
function resolveFoamVariable(variable: string) {
|
||||
if (variable === 'FOAM_TITLE') {
|
||||
return getFoamTitle();
|
||||
} else {
|
||||
return Promise.resolve(variable);
|
||||
}
|
||||
}
|
||||
|
||||
function resolveFoamVariables(variables: string[]) {
|
||||
const promises = variables.map(async variable =>
|
||||
Promise.resolve([variable, await resolveFoamVariable(variable)])
|
||||
);
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
export async function substituteFoamVariables(templateText: string) {
|
||||
const variables = findFoamVariables(templateText);
|
||||
const results = await resolveFoamVariables(variables);
|
||||
|
||||
const valueByName = new Map<string, string>();
|
||||
results.forEach(result => {
|
||||
valueByName.set(result[0], result[1]);
|
||||
});
|
||||
|
||||
variables.forEach(variable => {
|
||||
const regex = new RegExp(`\\\${${variable}}|\\$${variable}`, 'g');
|
||||
templateText = templateText.replace(regex, valueByName.get(variable));
|
||||
});
|
||||
|
||||
return templateText;
|
||||
}
|
||||
|
||||
async function createNoteFromTemplate(): Promise<void> {
|
||||
const templates = await getTemplates();
|
||||
if (templates.length === 0) {
|
||||
@@ -69,6 +121,12 @@ async function createNoteFromTemplate(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
const templateText = await workspace.fs.readFile(
|
||||
Uri.joinPath(templatesDir, selectedTemplate)
|
||||
);
|
||||
const subbedText = await substituteFoamVariables(templateText.toString());
|
||||
const snippet = new SnippetString(subbedText);
|
||||
|
||||
const defaultFileName = 'new-note.md';
|
||||
const defaultDir = Uri.joinPath(currentDir, defaultFileName);
|
||||
const filename = await window.showInputBox({
|
||||
@@ -89,10 +147,6 @@ async function createNoteFromTemplate(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
const templateText = await workspace.fs.readFile(
|
||||
Uri.joinPath(templatesDir, selectedTemplate)
|
||||
);
|
||||
const snippet = new SnippetString(templateText.toString());
|
||||
const filenameURI = Uri.file(filename);
|
||||
await workspace.fs.writeFile(filenameURI, new TextEncoder().encode(''));
|
||||
await focusNote(filenameURI, true);
|
||||
|
||||
@@ -3,7 +3,6 @@ import {
|
||||
workspace,
|
||||
ExtensionContext,
|
||||
commands,
|
||||
Range,
|
||||
ProgressLocation,
|
||||
} from 'vscode';
|
||||
import * as fs from 'fs';
|
||||
|
||||
@@ -23,7 +23,7 @@ export const markdownItWithFoamLinks = (
|
||||
) => {
|
||||
return md.use(markdownItRegex, {
|
||||
name: 'connect-wikilinks',
|
||||
regex: /\[\[([^\[\]]+?)\]\]/,
|
||||
regex: /\[\[([^[\]]+?)\]\]/,
|
||||
replace: (wikilink: string) => {
|
||||
try {
|
||||
const resource = workspace.find(wikilink);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Position, Range, Uri, workspace } from 'vscode';
|
||||
import { Position, Range, Uri } from 'vscode';
|
||||
import {
|
||||
Position as FoamPosition,
|
||||
Range as FoamRange,
|
||||
|
||||
Reference in New Issue
Block a user