[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:
Michael Overmeyer
2021-04-10 16:02:46 -04:00
committed by GitHub
parent 531bdab250
commit b1bdf766b1
6 changed files with 107 additions and 8 deletions

View File

@@ -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.

View File

@@ -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);
});
});

View File

@@ -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);

View File

@@ -3,7 +3,6 @@ import {
workspace,
ExtensionContext,
commands,
Range,
ProgressLocation,
} from 'vscode';
import * as fs from 'fs';

View File

@@ -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);

View File

@@ -1,4 +1,4 @@
import { Position, Range, Uri, workspace } from 'vscode';
import { Position, Range, Uri } from 'vscode';
import {
Position as FoamPosition,
Range as FoamRange,