Skip to content

Commit

Permalink
Add openDailyNote command and remove openTodayNote
Browse files Browse the repository at this point in the history
  • Loading branch information
svsool committed Jul 26, 2020
1 parent 4ae0457 commit 22c20c3
Show file tree
Hide file tree
Showing 10 changed files with 279 additions and 56 deletions.
10 changes: 7 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"activationEvents": [
"onLanguage:markdown",
"onCommand:memo.openRandomNote",
"onCommand:memo.openTodayNote",
"onCommand:memo.openDailyNote",
"onCommand:memo.openReferenceInDefaultApp",
"onCommand:_memo.openReference",
"onCommand:_memo.cacheWorkspace",
Expand All @@ -46,8 +46,8 @@
"markdown.markdownItPlugins": true,
"commands": [
{
"command": "memo.openTodayNote",
"title": "Open today's note",
"command": "memo.openDailyNote",
"title": "Open daily note",
"category": "Memo"
},
{
Expand Down Expand Up @@ -128,7 +128,9 @@
"@types/glob": "^7.1.1",
"@types/jest": "^26.0.7",
"@types/lodash.groupby": "^4.6.6",
"@types/lodash.range": "^3.2.6",
"@types/markdown-it": "^10.0.1",
"@types/moment": "^2.13.0",
"@types/node": "^14.0.25",
"@types/open": "^6.2.1",
"@types/rimraf": "^3.0.0",
Expand Down Expand Up @@ -158,8 +160,10 @@
"dependencies": {
"cross-path-sort": "^1.0.0",
"lodash.groupby": "^4.6.0",
"lodash.range": "^3.2.0",
"markdown-it": "^11.0.0",
"markdown-it-regex": "^0.2.0",
"moment": "^2.27.0",
"open": "^7.1.0"
}
}
4 changes: 2 additions & 2 deletions src/commands/commands.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import vscode from 'vscode';

import openDocumentByReference from './openDocumentByReference';
import openTodayNote from './openTodayNote';
import openRandomNote from './openRandomNote';
import openReferenceInDefaultApp from './openReferenceInDefaultApp';
import openDailyNote from './openDailyNote';
import { cacheWorkspace, cleanWorkspaceCache, getWorkspaceCache } from '../utils';

const commands = [
Expand All @@ -12,7 +12,7 @@ const commands = [
vscode.commands.registerCommand('_memo.cleanWorkspaceCache', cleanWorkspaceCache),
vscode.commands.registerCommand('_memo.getWorkspaceCache', getWorkspaceCache),
vscode.commands.registerCommand('memo.openRandomNote', openRandomNote),
vscode.commands.registerCommand('memo.openTodayNote', openTodayNote),
vscode.commands.registerCommand('memo.openDailyNote', openDailyNote),
vscode.commands.registerCommand('memo.openReferenceInDefaultApp', openReferenceInDefaultApp),
];

Expand Down
64 changes: 64 additions & 0 deletions src/commands/openDailyNote.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { commands, workspace } from 'vscode';
import moment from 'moment';

import openDailyNote from './openDailyNote';
import { closeEditorsAndCleanWorkspace } from '../test/testUtils';

describe('openDailyNote command', () => {
beforeEach(closeEditorsAndCleanWorkspace);

afterEach(closeEditorsAndCleanWorkspace);

it('should not fail on direct call', async () => {
expect(() => {
openDailyNote();
}).not.toThrow();

await commands.executeCommand('workbench.action.acceptSelectedQuickOpenItem');
});

it("should open today's note", async () => {
const today = moment().format('YYYY-MM-DD');

openDailyNote();

await commands.executeCommand('workbench.action.acceptSelectedQuickOpenItem');

const uris = await workspace.findFiles('**/*.md')!;

expect(uris).toHaveLength(1);

expect(uris[0].fsPath.endsWith(`${today}.md`)).toBe(true);
});

it("should open tomorrow's note", async () => {
const tomorrow = moment().add(1, 'day').format('YYYY-MM-DD');

openDailyNote();

await commands.executeCommand('workbench.action.quickOpenSelectNext');
await commands.executeCommand('workbench.action.acceptSelectedQuickOpenItem');

const uris = await workspace.findFiles('**/*.md')!;

expect(uris).toHaveLength(1);

expect(uris[0].fsPath.endsWith(`${tomorrow}.md`)).toBe(true);
});

it("should open yesterday's note", async () => {
const yesterday = moment().add(-1, 'day').format('YYYY-MM-DD');

openDailyNote();

await commands.executeCommand('workbench.action.quickOpenSelectNext');
await commands.executeCommand('workbench.action.quickOpenSelectNext');
await commands.executeCommand('workbench.action.acceptSelectedQuickOpenItem');

const uris = await workspace.findFiles('**/*.md')!;

expect(uris).toHaveLength(1);

expect(uris[0].fsPath.endsWith(`${yesterday}.md`)).toBe(true);
});
});
19 changes: 19 additions & 0 deletions src/commands/openDailyNote.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { commands } from 'vscode';

import { createDailyQuickPick } from '../utils';

const openDailyNote = () => {
const dailyQuickPick = createDailyQuickPick();

dailyQuickPick.onDidChangeSelection((selection) =>
commands.executeCommand('_memo.openDocumentByReference', {
reference: selection[0].detail,
}),
);

dailyQuickPick.onDidHide(() => dailyQuickPick.dispose());

dailyQuickPick.show();
};

export default openDailyNote;
40 changes: 0 additions & 40 deletions src/commands/openTodayNote.spec.ts

This file was deleted.

10 changes: 0 additions & 10 deletions src/commands/openTodayNote.ts

This file was deleted.

93 changes: 93 additions & 0 deletions src/utils/createDailyQuickPick.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import moment from 'moment';

import createDailyQuickPick from './createDailyQuickPick';
import { closeEditorsAndCleanWorkspace, createFile } from '../test/testUtils';

describe('createDailyQuickPick()', () => {
beforeEach(closeEditorsAndCleanWorkspace);

afterEach(closeEditorsAndCleanWorkspace);

it('should not fail on call', async () => {
expect(createDailyQuickPick).not.toThrow();
});

it.each(['Today', 'Yesterday', 'Tomorrow'])(
'should contain %s in the item label',
(labelSubstr) => {
const dailyQuickPick = createDailyQuickPick();

expect(dailyQuickPick.items.some((item) => item.label.includes(labelSubstr))).toBe(true);
},
);

it('should return 60 items (days) + 1 day (today)', () => {
const dailyQuickPick = createDailyQuickPick();

expect(dailyQuickPick.items).toHaveLength(63);
});

it('should contain an item with an indicator on note existence', async () => {
const dateInYYYYMMDDFormat = moment().format('YYYY-MM-DD');

await createFile(`${dateInYYYYMMDDFormat}.md`);

const dailyQuickPick = createDailyQuickPick();

const quickPickItem = dailyQuickPick.items.find((item) => item.description === 'Exists')!;

expect(quickPickItem).not.toBeFalsy();

expect([...quickPickItem.label][0]).toMatchInlineSnapshot(`"✓"`);
});

it('should return all items with an indicator about missing note', async () => {
const dailyQuickPick = createDailyQuickPick();

expect(dailyQuickPick.items.every((item) => item.description === 'Missing')).toBe(true);

expect([...dailyQuickPick.items[0].label][0]).toMatchInlineSnapshot(`"✕"`);
});

it('should be able to provide items older than one month', async () => {
await createFile('2000-01-01.md');
await createFile('2000-01-02.md');
await createFile('2000-01-03.md');

const dailyQuickPick = createDailyQuickPick();

const item1 = dailyQuickPick.items.find((item) => item.detail === '2000-01-01')!;
const item2 = dailyQuickPick.items.find((item) => item.detail === '2000-01-02')!;
const item3 = dailyQuickPick.items.find((item) => item.detail === '2000-01-03')!;

expect(dailyQuickPick.items).toHaveLength(66);

expect(item1).not.toBeFalsy();
expect(item2).not.toBeFalsy();
expect(item3).not.toBeFalsy();
});

it('should be able to provide items newer than one month', async () => {
const now = moment();

const note1 = `${now.clone().add(60, 'days').format('YYYY-MM-DD')}`;
const note2 = `${now.clone().add(61, 'days').format('YYYY-MM-DD')}`;
const note3 = `${now.clone().add(62, 'days').format('YYYY-MM-DD')}`;

await createFile(`${note1}.md`);
await createFile(`${note2}.md`);
await createFile(`${note3}.md`);

const dailyQuickPick = createDailyQuickPick();

const item1 = dailyQuickPick.items.find((item) => item.detail === note1)!;
const item2 = dailyQuickPick.items.find((item) => item.detail === note2)!;
const item3 = dailyQuickPick.items.find((item) => item.detail === note3)!;

expect(dailyQuickPick.items).toHaveLength(66);

expect(item1).not.toBeFalsy();
expect(item2).not.toBeFalsy();
expect(item3).not.toBeFalsy();
});
});
68 changes: 68 additions & 0 deletions src/utils/createDailyQuickPick.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import moment from 'moment';
import range from 'lodash.range';
import path from 'path';
import { window } from 'vscode';

import { findUriByRef, getWorkspaceCache } from './utils';

const toOffsetLabel = (dayOffset: number) => {
if (dayOffset === -1) {
return '-1 day Yesterday';
} else if (dayOffset === 0) {
return 'Today';
} else if (dayOffset === 1) {
return '+1 day Tomorrow';
}

return `${dayOffset > 0 ? '+' : ''}${dayOffset} days`;
};

const yyyymmddRegExp = /([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))/;

const createQuickPick = () => {
const now = moment().startOf('day');
const allDailyDates = getWorkspaceCache()
.markdownUris.map((uri) => path.parse(uri.fsPath).name)
.filter((name) => yyyymmddRegExp.exec(name) && moment(name).isValid());
const existingDayOffsets = allDailyDates.map((dateStr) =>
moment(dateStr).startOf('day').diff(now, 'days'),
);
const pastDayOffsets = existingDayOffsets
.filter((dayOffset) => dayOffset <= -32)
.sort((a, b) => b - a);
const futureDayOffsets = existingDayOffsets
.filter((dayOffset) => dayOffset >= 32)
.sort((a, b) => a - b);

const dayOffsets = [
0, // Today
1, // Tomorrow
-1, // Yesterday
...range(2, 32), // Next month
...futureDayOffsets,
...range(-2, -32), // Prev month
...pastDayOffsets,
];
const quickPick = window.createQuickPick();

quickPick.matchOnDescription = true;
quickPick.matchOnDetail = true;

quickPick.items = dayOffsets.map((dayOffset) => {
const date = now.clone().add(dayOffset, 'day');
const dateYYYYMMDD = date.format('YYYY-MM-DD');
const ref = findUriByRef(getWorkspaceCache().markdownUris, dateYYYYMMDD);

return {
label: `${ref ? '✓' : '✕'} ${toOffsetLabel(dayOffset)} | ${date.format(
'dddd, MMMM D, YYYY',
)}`,
description: ref ? 'Exists' : 'Missing',
detail: dateYYYYMMDD,
};
});

return quickPick;
};

export default createQuickPick;
3 changes: 2 additions & 1 deletion src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import fs from 'fs';
import getWordRangeAtPosition from './getWordRangeAtPosition';
import { WorkspaceCache, RefT, FoundRefT } from '../types';
import { isInCodeSpan, isInFencedCodeBlock } from './externalUtils';
import { default as createDailyQuickPick } from './createDailyQuickPick';

export { sortPaths };
export { sortPaths, createDailyQuickPick };

const markdownExtRegex = /\.md$/i;

Expand Down
Loading

0 comments on commit 22c20c3

Please sign in to comment.