Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for target date variables in daily note template #781

Merged
merged 9 commits into from
Oct 27, 2021
40 changes: 35 additions & 5 deletions docs/features/note-templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,42 @@ Templates can use all the variables available in [VS Code Snippets](https://code

In addition, you can also use variables provided by Foam:

| Name | Description |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `FOAM_SELECTED_TEXT` | Foam will fill it with selected text when creating a new note, if any text is selected. Selected text will be replaced with a wikilink to the new note. |
| `FOAM_TITLE` | The title of the note. If used, Foam will prompt you to enter a title for the note. |
| Name | Description |
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `FOAM_SELECTED_TEXT` | Foam will fill it with selected text when creating a new note, if any text is selected. Selected text will be replaced with a wikilink to the new note. |
| `FOAM_TITLE` | The title of the note. If used, Foam will prompt you to enter a title for the note. |
| `FOAM_DATE_*` | `FOAM_DATE_YEAR`, `FOAM_DATE_MONTH`, etc. Foam-specific versions of [VS Code's datetime snippet variables](https://code.visualstudio.com/docs/editor/userdefinedsnippets#_variables). Prefer these versions over VS Code's. |

**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.
**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. See [#693](https://github.com/foambubble/foam/issues/693).

### `FOAM_DATE_*` variables

Foam defines its own set of datetime variables that have a similar behaviour as [VS Code's datetime snippet variables](https://code.visualstudio.com/docs/editor/userdefinedsnippets#_variables).

For example, `FOAM_DATE_YEAR` has the same behaviour as VS Code's `CURRENT_YEAR`, `FOAM_DATE_SECONDS_UNIX` has the same behaviour as `CURRENT_SECONDS_UNIX`, etc.

By default, prefer using the `FOAM_DATE_` versions. The datetime used to compute the values will be the same for both `FOAM_DATE_` and VS Code's variables, with the exception of the creation notes using the daily note template.

#### Relative daily notes

When referring to daily notes, you can use the relative snippets (`/+1d`, `/tomorrow`, etc.). In these cases, the new notes will be created with the daily note template, but the datetime used should be the relative datetime, not the current datetime.
By using the `FOAM_DATE_` versions of the variables, the correct relative date will populate the variables, instead of the current datetime.

For example, given this daily note template (`.foam/templates/daily-note.md`):

```markdown
# $FOAM_DATE_YEAR-$FOAM_DATE_MONTH-$FOAM_DATE_DATE

## Here's what I'm going to do today

* Thing 1
* Thing 2
```

When the `/tomorrow` snippet is used, `FOAM_DATE_` variables will be populated with tomorrow's date, as expected.
If instead you were to use the VS Code versions of these variables, they would be populated with today's date, not tomorrow's, causing unexpected behaviour.

When creating notes in any other scenario, the `FOAM_DATE_` values are computed using the same datetime as the VS Code ones, so the `FOAM_DATE_` versions can be used in all scenarios by default.

## Metadata

Expand Down
12 changes: 8 additions & 4 deletions packages/foam-vscode/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable changes to the "foam-vscode" extension will be documented in this fi

Check [Keep a Changelog](https://keepachangelog.com/) for recommendations on how to structure this file.

## Unreleased

- Added `FOAM_DATE_*` template variables (#781)

## [0.15.1] - 2021-10-21

Fixes and Improvements:
Expand All @@ -25,7 +29,7 @@ Fixes and Improvements:

## [0.14.2] - 2021-07-24

Features:
Features:

- Autocompletion for tags (#708 - thanks @pderaaij)
- Use templates for new note created from wikilink (#712 - thanks @movermeyer)
Expand All @@ -42,7 +46,7 @@ Fixes and Improvements:

## [0.14.0] - 2021-07-13

Features:
Features:

- Create new note from selection (#666 - thanks @pderaaij)
- Use templates for daily notes (#700 - thanks @movermeyer)
Expand Down Expand Up @@ -70,9 +74,9 @@ Fixes and Improvements:

- Fixed #667, incorrect resolution of foam-core library

Internal:
Internal:

- BREAKING CHANGE: Removed Foam local plugins
- BREAKING CHANGE: Removed Foam local plugins
If you were previously using the alpha feature of Foam local plugins you will soon be able to migrate the functionality to the V1 API

## [0.13.6] - 2021-06-05
Expand Down
50 changes: 49 additions & 1 deletion packages/foam-vscode/src/dated-notes.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { workspace } from 'vscode';
import { getDailyNotePath } from './dated-notes';
import { createDailyNoteIfNotExists, getDailyNotePath } from './dated-notes';
import { URI } from './core/model/uri';
import { isWindows } from './utils';
import {
cleanWorkspace,
closeEditors,
createFile,
showInEditor,
} from './test/test-utils-vscode';

describe('getDailyNotePath', () => {
const date = new Date('2021-02-07T00:00:00Z');
Expand All @@ -19,6 +25,9 @@ describe('getDailyNotePath', () => {
`${isoDate}.md`
);

const oldValue = await workspace
.getConfiguration('foam')
.get('openDailyNote.directory');
await workspace
.getConfiguration('foam')
.update('openDailyNote.directory', config);
Expand All @@ -27,6 +36,10 @@ describe('getDailyNotePath', () => {
expect(URI.toFsPath(getDailyNotePath(foamConfiguration, date))).toEqual(
URI.toFsPath(expectedPath)
);

await workspace
.getConfiguration('foam')
.update('openDailyNote.directory', oldValue);
});

test('Uses absolute directories without modification', async () => {
Expand All @@ -37,6 +50,10 @@ describe('getDailyNotePath', () => {
? `${config}\\${isoDate}.md`
: `${config}/${isoDate}.md`;

const oldValue = await workspace
.getConfiguration('foam')
.get('openDailyNote.directory');

await workspace
.getConfiguration('foam')
.update('openDailyNote.directory', config);
Expand All @@ -45,5 +62,36 @@ describe('getDailyNotePath', () => {
expect(URI.toFsPath(getDailyNotePath(foamConfiguration, date))).toMatch(
expectedPath
);

await workspace
.getConfiguration('foam')
.update('openDailyNote.directory', oldValue);
});
});

describe('Daily note template', () => {
it('Uses the daily note variables in the template', async () => {
const targetDate = new Date(2021, 8, 12);

// eslint-disable-next-line no-template-curly-in-string
await createFile('hello ${FOAM_DATE_MONTH_NAME} ${FOAM_DATE_DATE} hello', [
'.foam',
'templates',
'daily-note.md',
]);

const config = workspace.getConfiguration('foam');
const uri = getDailyNotePath(config, targetDate);

await createDailyNoteIfNotExists(config, uri, targetDate);

const doc = await showInEditor(uri);
const content = doc.editor.document.getText();
expect(content).toEqual('hello September 12 hello');
});

afterAll(async () => {
await cleanWorkspace();
await closeEditors();
});
});
25 changes: 11 additions & 14 deletions packages/foam-vscode/src/dated-notes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { createNoteFromDailyNoteTemplate } from './features/create-from-template
*
* @param date A given date to be formatted as filename.
*/
async function openDailyNoteFor(date?: Date) {
export async function openDailyNoteFor(date?: Date) {
const foamConfiguration = workspace.getConfiguration('foam');
const currentDate = date !== undefined ? date : new Date();

Expand All @@ -40,7 +40,7 @@ async function openDailyNoteFor(date?: Date) {
* @param date A given date to be formatted as filename.
* @returns The path to the daily note file.
*/
function getDailyNotePath(
export function getDailyNotePath(
configuration: WorkspaceConfiguration,
date: Date
): URI {
Expand Down Expand Up @@ -70,7 +70,7 @@ function getDailyNotePath(
* @param date A given date to be formatted as filename.
* @returns The daily note's filename.
*/
function getDailyNoteFileName(
export function getDailyNoteFileName(
configuration: WorkspaceConfiguration,
date: Date
): string {
Expand All @@ -95,10 +95,10 @@ function getDailyNoteFileName(
* @param currentDate The current date, to be used as a title.
* @returns Wether the file was created.
*/
async function createDailyNoteIfNotExists(
export async function createDailyNoteIfNotExists(
configuration: WorkspaceConfiguration,
dailyNotePath: URI,
currentDate: Date
targetDate: Date
) {
if (await pathExists(dailyNotePath)) {
return false;
Expand All @@ -113,17 +113,14 @@ foam_template:
name: New Daily Note
description: Foam's default daily note template
---
# ${dateFormat(currentDate, titleFormat, false)}
# ${dateFormat(targetDate, titleFormat, false)}
`;

await createNoteFromDailyNoteTemplate(dailyNotePath, templateFallbackText);
await createNoteFromDailyNoteTemplate(
dailyNotePath,
templateFallbackText,
targetDate
);

return true;
}

export {
openDailyNoteFor,
getDailyNoteFileName,
createDailyNoteIfNotExists,
getDailyNotePath,
};
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,83 @@ describe('resolveFoamVariables', () => {
expected
);
});

test('Resolves FOAM_DATE_* properties with current day by default', async () => {
const variables = [
'FOAM_DATE_YEAR',
'FOAM_DATE_YEAR_SHORT',
'FOAM_DATE_MONTH',
'FOAM_DATE_MONTH_NAME',
'FOAM_DATE_MONTH_NAME_SHORT',
'FOAM_DATE_DATE',
'FOAM_DATE_DAY_NAME',
'FOAM_DATE_DAY_NAME_SHORT',
'FOAM_DATE_HOUR',
'FOAM_DATE_MINUTE',
'FOAM_DATE_SECOND',
riccardoferretti marked this conversation as resolved.
Show resolved Hide resolved
'FOAM_DATE_SECONDS_UNIX',
];

const expected = new Map<string, string>();
expected.set(
'FOAM_DATE_YEAR',
new Date().toLocaleString('default', { year: 'numeric' })
);
expected.set(
'FOAM_DATE_MONTH_NAME',
new Date().toLocaleString('default', { month: 'long' })
);
expected.set(
'FOAM_DATE_DATE',
new Date().toLocaleString('default', { day: '2-digit' })
);
const givenValues = new Map<string, string>();

expect(await resolveFoamVariables(variables, givenValues)).toEqual(
expect.objectContaining(expected)
);
});

test('Resolves FOAM_DATE_* properties with given date', async () => {
const targetDate = new Date(2021, 8, 12, 1, 2, 3);
const variables = [
'FOAM_DATE_YEAR',
'FOAM_DATE_YEAR_SHORT',
'FOAM_DATE_MONTH',
'FOAM_DATE_MONTH_NAME',
riccardoferretti marked this conversation as resolved.
Show resolved Hide resolved
'FOAM_DATE_MONTH_NAME_SHORT',
'FOAM_DATE_DATE',
'FOAM_DATE_DAY_NAME',
'FOAM_DATE_DAY_NAME_SHORT',
'FOAM_DATE_HOUR',
'FOAM_DATE_MINUTE',
'FOAM_DATE_SECOND',
'FOAM_DATE_SECONDS_UNIX',
];

const expected = new Map<string, string>();
expected.set('FOAM_DATE_YEAR', '2021');
expected.set('FOAM_DATE_YEAR_SHORT', '21');
expected.set('FOAM_DATE_MONTH', '09');
expected.set('FOAM_DATE_MONTH_NAME', 'September');
expected.set('FOAM_DATE_MONTH_NAME_SHORT', 'Sep');
expected.set('FOAM_DATE_DATE', '12');
expected.set('FOAM_DATE_DAY_NAME', 'Sunday');
expected.set('FOAM_DATE_DAY_NAME_SHORT', 'Sun');
expected.set('FOAM_DATE_HOUR', '01');
expected.set('FOAM_DATE_MINUTE', '02');
expected.set('FOAM_DATE_SECOND', '03');
expected.set(
'FOAM_DATE_SECONDS_UNIX',
(targetDate.getTime() / 1000).toString()
);

const givenValues = new Map<string, string>();

expect(
await resolveFoamVariables(variables, givenValues, targetDate)
).toEqual(expected);
});
});

describe('resolveFoamTemplateVariables', () => {
Expand Down
Loading