Skip to content

Commit

Permalink
Add name and description template metadata attributes
Browse files Browse the repository at this point in the history
These are displayed in the template picker
  • Loading branch information
movermeyer committed May 30, 2021
1 parent 0d4aa08 commit ca5bf10
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 8 deletions.
96 changes: 89 additions & 7 deletions packages/foam-vscode/src/features/create-from-template.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import {
window,
commands,
ExtensionContext,
workspace,
QuickPickItem,
SnippetString,
Uri,
window,
workspace,
} from 'vscode';
import * as path from 'path';
import { FoamFeature } from '../types';
Expand All @@ -31,7 +32,13 @@ export class UserCancelledOperation extends Error {

const knownFoamVariables = new Set(['FOAM_TITLE']);

const defaultTemplateDefaultText: string = '# ${FOAM_TITLE}'; // eslint-disable-line no-template-curly-in-string
const defaultTemplateDefaultText: string = `---
foam_template:
name: New Note
description: Foam's default new note template
---
# \${FOAM_TITLE}
`;
const defaultTemplateUri = Uri.joinPath(templatesDir, 'new-note.md');

const templateContent = `# \${1:$TM_FILENAME_BASE}
Expand All @@ -53,9 +60,21 @@ For a full list of features see [the VS Code snippets page](https://code.visuals
2. create a note from this template by running the \`Foam: Create New Note From Template\` command
`;

async function getTemplates(): Promise<string[]> {
async function templateMetadata(templateUri: Uri): Promise<object> {
const contents = await workspace.fs
.readFile(templateUri)
.then(bytes => bytes.toString());
let templateMetadata: object, _templateWithFoamFrontmatterRemoved: string;
[
templateMetadata,
_templateWithFoamFrontmatterRemoved,
] = extractFoamTemplateFrontmatterMetadata(contents);
return templateMetadata;
}

async function getTemplates(): Promise<Uri[]> {
const templates = await workspace.findFiles('.foam/templates/**.md');
return templates.map(template => path.basename(template.path));
return templates;
}

async function offerToCreateTemplate(): Promise<void> {
Expand Down Expand Up @@ -155,12 +174,73 @@ export function substituteFoamVariables(
return templateText;
}

function sortTemplatesMetadata(templatesMetadata: object[]) {
// Sort by name's existence, name, then path
return templatesMetadata.sort((t1, t2) => {
if (t1['name'] === undefined && t2['name'] !== undefined) {
return 1;
}

if (t1['name'] !== undefined && t2['name'] === undefined) {
return -1;
}

if (t1['name'] > t2['name']) {
return 1;
}

if (t1['name'] < t2['name']) {
return -1;
}

if (t1['templatePath'] > t2['templatePath']) {
return 1;
}

if (t1['templatePath'] < t2['templatePath']) {
return -1;
}

return 0;
});
}

async function askUserForTemplate() {
const templates = await getTemplates();
if (templates.length === 0) {
return offerToCreateTemplate();
}
return await window.showQuickPick(templates, {

const templatesMetadata = sortTemplatesMetadata(
await Promise.all(
templates.map(async templateUri => {
const metadata = await templateMetadata(templateUri);
metadata['templatePath'] = path.basename(templateUri.path);
return metadata;
})
)
);

const items: QuickPickItem[] = await Promise.all(
templatesMetadata.map(metadata => {
const label = metadata['name'] || metadata['templatePath'];
const description = metadata['name'] ? metadata['templatePath'] : null;
const detail = metadata['description'];
const item = {
label: label,
description: description,
detail: detail,
};
Object.keys(item).forEach(key => {
if (!item[key]) {
delete item[key];
}
});
return item;
})
);

return await window.showQuickPick(items, {
placeHolder: 'Select a template to use.',
});
}
Expand Down Expand Up @@ -300,7 +380,9 @@ async function createNoteFromTemplate(
if (selectedTemplate === undefined) {
return;
}
templateFilename = selectedTemplate as string;
templateFilename =
(selectedTemplate as QuickPickItem).description ||
(selectedTemplate as QuickPickItem).label;
const templateUri = Uri.joinPath(templatesDir, templateFilename);
const templateText = await workspace.fs
.readFile(templateUri)
Expand Down
14 changes: 14 additions & 0 deletions packages/foam-vscode/src/utils/template-frontmatter-parser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ foo: bar
test('Returns the `foam_template` metadata when it is used in its own frontmatter block', () => {
const input = `---
foam_template:
name: My Note Template
description: This is my note template
filepath: journal/$CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE_$FOAM_TITLE.md
---
Expand All @@ -73,6 +75,8 @@ foam_template:

const expected = [
{
name: 'My Note Template',
description: 'This is my note template',
filepath:
'journal/$CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE_$FOAM_TITLE.md',
},
Expand All @@ -86,6 +90,8 @@ foam_template:
const input = `---
foam_template:
filepath: journal/$CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE_$FOAM_TITLE.md
description: This is my note template
name: My Note Template
---
---
Expand Down Expand Up @@ -116,6 +122,8 @@ more_metadata: *info
{
filepath:
'journal/$CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE_$FOAM_TITLE.md',
description: 'This is my note template',
name: 'My Note Template',
},
output,
];
Expand All @@ -127,7 +135,9 @@ more_metadata: *info
const input = `---
foo: bar
foam_template:
name: My Note Template
filepath: journal/$CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE_$FOAM_TITLE.md
description: This is my note template
# A YAML comment
metadata: &info
title: The Gentlemen
Expand All @@ -150,8 +160,10 @@ more_metadata: *info

const expected = [
{
name: 'My Note Template',
filepath:
'journal/$CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE_$FOAM_TITLE.md',
description: 'This is my note template',
},
output,
];
Expand All @@ -165,7 +177,9 @@ describe('removeFoamMetadata', () => {
const input = `---
foo: bar
foam_template: &foam_template # A YAML comment
description: This is my note template
filepath: journal/$CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE_$FOAM_TITLE.md # A YAML comment
name: My Note Template
# A YAML comment
metadata: &info
title: The Gentlemen
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,8 @@ export function extractFoamTemplateFrontmatterMetadata(
}

export function removeFoamMetadata(contents: string) {
return contents.replace(/^\s*foam_template:.*?\n\s*filepath:.*\n/gm, '');
return contents.replace(
/^\s*foam_template:.*?\n(?:\s*(?:filepath|name|description):.*\n)+/gm,
''
);
}

0 comments on commit ca5bf10

Please sign in to comment.