Compare commits

...

14 Commits

Author SHA1 Message Date
Riccardo Ferretti
7e740fec0f v0.13.8 2021-07-02 20:02:27 +02:00
Riccardo Ferretti
beae852c21 Prepare for next release 2021-07-02 19:48:52 +02:00
Paul de Raaij
85e857d973 handle different capitalizations of wikilinks and files (#688) 2021-07-02 19:41:24 +02:00
José Duarte
667eee0e10 Add documentation to the dated-notes.ts file (#690)
* Add docs to `createDailyNoteDirectoryIfNotExists`

* Add docs to `createDailyNoteIfNotExists`

* Capitalize doc strings

* Add docs to `getDailyNoteFileName`

* Update the @configuration parameter docs

* Add docs to `getDailyNotePath`

* Add docs to `openDailyNoteFor`

* Update packages/foam-vscode/src/dated-notes.ts

Co-authored-by: Michael Overmeyer <michael.overmeyer@shopify.com>

* Update packages/foam-vscode/src/dated-notes.ts

Co-authored-by: Michael Overmeyer <michael.overmeyer@shopify.com>

* Polish some of the comments

Co-authored-by: José Duarte <jmg.duarte@campus.fct.unl.pt!>
Co-authored-by: Michael Overmeyer <michael.overmeyer@shopify.com>
2021-06-28 14:55:14 +02:00
dependabot[bot]
b6e68b3605 Bump glob-parent from 5.1.1 to 5.1.2 in /packages/foam-core (#678)
Bumps [glob-parent](https://github.com/gulpjs/glob-parent) from 5.1.1 to 5.1.2.
- [Release notes](https://github.com/gulpjs/glob-parent/releases)
- [Changelog](https://github.com/gulpjs/glob-parent/blob/main/CHANGELOG.md)
- [Commits](https://github.com/gulpjs/glob-parent/compare/v5.1.1...v5.1.2)

---
updated-dependencies:
- dependency-name: glob-parent
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-06-24 23:57:34 +02:00
Paul de Raaij
b9b0f9b515 Allow for dots in wikilinks (#689) 2021-06-24 23:20:03 +02:00
dependabot[bot]
95399977ec Bump hosted-git-info from 2.8.8 to 2.8.9 (#686)
Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.8 to 2.8.9.
- [Release notes](https://github.com/npm/hosted-git-info/releases)
- [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md)
- [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.8...v2.8.9)

---
updated-dependencies:
- dependency-name: hosted-git-info
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-06-21 18:15:13 +02:00
dependabot[bot]
f759e7cd6e Bump ws from 5.2.2 to 5.2.3 in /packages/foam-core (#685)
Bumps [ws](https://github.com/websockets/ws) from 5.2.2 to 5.2.3.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/5.2.2...5.2.3)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-06-21 18:14:46 +02:00
Riccardo Ferretti
5839455535 fixed bug in date snippet
thanks to @syndenham-chorea for reporting and directing the fix
see https://discord.com/channels/729975036148056075/729975036664086560/855628250414972998
2021-06-21 00:28:45 +02:00
Riccardo Ferretti
7e4ae82fe1 updated foam-core dependency 2021-06-21 00:25:13 +02:00
Scott Bronson
e47155424f doc: describe how to select launch configuration (#674) 2021-06-12 00:19:57 +02:00
allcontributors[bot]
903a191394 docs: add bronson as a contributor for doc (#677)
* docs: update docs/index.md [skip ci]

* docs: update readme.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2021-06-12 00:17:33 +02:00
Scott Bronson
5c6212dc96 remove broken link to adding-a-new-command (#675)
This file was removed by deb77328c0 last Dec.
2021-06-12 00:16:05 +02:00
Paul de Raaij
bca9756e2b Revive support for basic link alias (#656)
* Add support for basic link aliases

* Refactor to future link model

* Refactor preview behavior for aliases

* Refactore use of NoteSource

* Remove references from ref block  before processing links

Co-authored-by: Jani Eväkallio <jani.evakallio@gmail.com>
2021-06-09 23:07:10 +02:00
23 changed files with 295 additions and 82 deletions

View File

@@ -697,6 +697,15 @@
"contributions": [
"code"
]
},
{
"login": "bronson",
"name": "Scott Bronson",
"avatar_url": "https://avatars.githubusercontent.com/u/1776?v=4",
"profile": "https://github.com/bronson",
"contributions": [
"doc"
]
}
],
"contributorsPerLine": 7,

View File

@@ -56,16 +56,12 @@ Tests in `foam-vscode` live alongside the code in `src`.
This guide assumes you read the previous instructions and you're set up to work on Foam.
1. Now we'll use the launch configuration defined at [`.vscode/launch.json`](https://github.com/foambubble/foam/blob/master/.vscode/launch.json) to start a new extension host of VS Code. From the root, or the `foam-vscode` workspace, press f5.
1. Now we'll use the launch configuration defined at [`.vscode/launch.json`](https://github.com/foambubble/foam/blob/master/.vscode/launch.json) to start a new extension host of VS Code. Open the "Run and Debug" Activity (the icon with the bug on the far left) and select "Run VSCode Extension" in the pop-up menu. Now hit F5 or click the green arrow "play" button to fire up a new copy of VS Code with your extension installed.
2. In the new extension host of VS Code that launched, open a Foam workspace (e.g. your personal one, or a test-specific one created from [foam-template](https://github.com/foambubble/foam-template)). This is strictly not necessary, but the extension won't auto-run unless it's in a workspace with a `.vscode/foam.json` file.
3. Test a command to make sure it's working as expected. Open the Command Palette (Ctrl/Cmd + Shift + P) and select "Foam: Update Markdown Reference List". If you see no errors, it's good to go!
For more resources related to the VS Code Extension, check out the links below:
- [[tutorial-adding-a-new-command-to-the-vs-code-extension]]
---
Feel free to modify and submit a PR if this guide is out-of-date or contains errors!

View File

@@ -202,6 +202,7 @@ If that sounds like something you're interested in, I'd love to have you along o
<td align="center"><a href="https://github.com/Barabazs"><img src="https://avatars.githubusercontent.com/u/31799121?v=4?s=60" width="60px;" alt=""/><br /><sub><b>Barabas</b></sub></a><br /><a href="https://github.com/foambubble/foam/commits?author=Barabazs" title="Code">💻</a></td>
<td align="center"><a href="http://enginveske@gmail.com"><img src="https://avatars.githubusercontent.com/u/43685404?v=4?s=60" width="60px;" alt=""/><br /><sub><b>Engincan VESKE</b></sub></a><br /><a href="https://github.com/foambubble/foam/commits?author=EngincanV" title="Documentation">📖</a></td>
<td align="center"><a href="http://www.paulderaaij.nl"><img src="https://avatars.githubusercontent.com/u/495374?v=4?s=60" width="60px;" alt=""/><br /><sub><b>Paul de Raaij</b></sub></a><br /><a href="https://github.com/foambubble/foam/commits?author=pderaaij" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/bronson"><img src="https://avatars.githubusercontent.com/u/1776?v=4?s=60" width="60px;" alt=""/><br /><sub><b>Scott Bronson</b></sub></a><br /><a href="https://github.com/foambubble/foam/commits?author=bronson" title="Documentation">📖</a></td>
</tr>
</table>

View File

@@ -4,5 +4,5 @@
],
"npmClient": "yarn",
"useWorkspaces": true,
"version": "0.13.7"
"version": "0.13.8"
}

View File

@@ -1,7 +1,7 @@
{
"name": "foam-core",
"repository": "https://github.com/foambubble/foam",
"version": "0.13.7",
"version": "0.13.8",
"license": "MIT",
"files": [
"dist"

View File

@@ -31,9 +31,11 @@ import { ResourceProvider } from 'model/provider';
import { IDataStore, FileDataStore, IMatcher } from './services/datastore';
import { IDisposable } from 'common/lifecycle';
const ALIAS_DIVIDER_CHAR = '|';
export interface ParserPlugin {
name?: string;
visit?: (node: Node, note: Resource) => void;
visit?: (node: Node, note: Resource, noteSource: string) => void;
onDidInitializeParser?: (parser: unified.Processor) => void;
onWillParseMarkdown?: (markdown: string) => string;
onWillVisitTree?: (tree: Node, note: Resource) => void;
@@ -121,7 +123,7 @@ export class MarkdownResourceProvider implements ResourceProvider {
switch (link.type) {
case 'wikilink':
const definitionUri = resource.definitions.find(
def => def.label === link.slug
def => def.label === link.target
)?.url;
if (isSome(definitionUri)) {
const definedUri = URI.resolve(definitionUri, resource.uri);
@@ -130,8 +132,8 @@ export class MarkdownResourceProvider implements ResourceProvider {
URI.placeholder(definedUri.path);
} else {
targetUri =
workspace.find(link.slug, resource.uri)?.uri ??
URI.placeholder(link.slug);
workspace.find(link.target, resource.uri)?.uri ??
URI.placeholder(link.target);
}
break;
@@ -197,12 +199,28 @@ const titlePlugin: ParserPlugin = {
const wikilinkPlugin: ParserPlugin = {
name: 'wikilink',
visit: (node, note) => {
visit: (node, note, noteSource) => {
if (node.type === 'wikiLink') {
const text = node.value as string;
const alias = node.data?.alias as string;
const literalContent = noteSource.substring(
node.position!.start.offset!,
node.position!.end.offset!
);
const hasAlias =
literalContent !== text && literalContent.includes(ALIAS_DIVIDER_CHAR);
note.links.push({
type: 'wikilink',
slug: node.value as string,
target: node.value as string,
rawText: literalContent,
label: hasAlias
? alias.trim()
: literalContent.substring(2, literalContent.length - 2),
target: hasAlias
? literalContent
.substring(2, literalContent.indexOf(ALIAS_DIVIDER_CHAR))
.trim()
: text.trim(),
range: astPositionToFoamRange(node.position!),
});
}
@@ -259,7 +277,7 @@ export function createMarkdownParser(
const parser = unified()
.use(markdownParse, { gfm: true })
.use(frontmatterPlugin, ['yaml'])
.use(wikiLinkPlugin);
.use(wikiLinkPlugin, { aliasDivider: ALIAS_DIVIDER_CHAR });
const plugins = [
titlePlugin,
@@ -342,7 +360,7 @@ export function createMarkdownParser(
for (let i = 0, len = plugins.length; i < len; i++) {
try {
plugins[i].visit?.(node, note);
plugins[i].visit?.(node, note, markdown);
} catch (e) {
handleError(plugins[i], 'visit', uri, e);
}
@@ -431,7 +449,14 @@ export function createMarkdownReferences(
: dropExtension(relativePath);
// [wiki-link-text]: path/to/file.md "Page title"
return { label: link.slug, url: pathToNote, title: target.title };
return {
label:
link.rawText.indexOf('[[') > -1
? link.rawText.substring(2, link.rawText.length - 2)
: link.rawText || link.label,
url: pathToNote,
title: target.title,
};
})
.filter(isSome)
.sort();

View File

@@ -11,8 +11,9 @@ export interface NoteSource {
export interface WikiLink {
type: 'wikilink';
slug: string;
target: string;
label: string;
rawText: string;
range: Range;
}

View File

@@ -26,7 +26,8 @@ const pathToResourceId = (pathValue: string) => {
};
const uriToResourceId = (uri: URI) => pathToResourceId(uri.path);
const pathToResourceName = (pathValue: string) => path.parse(pathValue).name;
const pathToResourceName = (pathValue: string) =>
path.parse(pathValue).name.toLowerCase();
export const uriToResourceName = (uri: URI) => pathToResourceName(uri.path);
export class FoamWorkspace implements IDisposable {
@@ -110,7 +111,12 @@ export class FoamWorkspace implements IDisposable {
case 'key':
const name = pathToResourceName(resourceId as string);
const paths = this.resourcesByName[name];
let paths = this.resourcesByName[name];
if (isNone(paths) || paths.length === 0) {
paths = this.resourcesByName[resourceId as string];
}
if (isNone(paths) || paths.length === 0) {
return null;
}
@@ -118,6 +124,7 @@ export class FoamWorkspace implements IDisposable {
const sortedPaths = paths.length === 1
? paths
: paths.sort((a, b) => a.localeCompare(b));
return this.resources[sortedPaths[0]];
case 'absolute-path':

View File

@@ -67,10 +67,10 @@ export const createTestNote = (params: {
return 'slug' in link
? {
type: 'wikilink',
slug: link.slug,
target: link.slug,
label: link.slug,
range: range,
text: 'link text',
rawText: 'link text',
}
: {
type: 'link',

View File

@@ -3,7 +3,7 @@ import {
createMarkdownReferences,
ParserPlugin,
} from '../src/markdown-provider';
import { DirectLink } from '../src/model/note';
import { DirectLink, WikiLink } from '../src/model/note';
import { Logger } from '../src/utils/log';
import { uriToSlug } from '../src/utils/slug';
import { URI } from '../src/model/uri';
@@ -130,6 +130,24 @@ this is a [link to intro](#introduction)
noteE.uri,
]);
});
it('Parses backlinks with an alias', () => {
const note = createNoteFromMarkdown(
'/path/to/page-a.md',
'this is [[link|link alias]]. A link with spaces [[other link | spaced]]'
);
expect(note.links.length).toEqual(2);
let link = note.links[0] as WikiLink;
expect(link.type).toEqual('wikilink');
expect(link.rawText).toEqual('[[link|link alias]]');
expect(link.label).toEqual('link alias');
expect(link.target).toEqual('link');
link = note.links[1] as WikiLink;
expect(link.type).toEqual('wikilink');
expect(link.rawText).toEqual('[[other link | spaced]]');
expect(link.label).toEqual('spaced');
expect(link.target).toEqual('other link');
});
});
describe('Note Title', () => {
@@ -336,19 +354,6 @@ this is some #text that includes #tags we #care-about.
new Set(['text', 'tags', 'care-about', 'hello', 'world', 'this_is_good'])
);
});
it('can find nested tags as array in yaml', () => {
const noteA = createNoteFromMarkdown(
'/dir1/page-a.md',
`
---
tags: [hello, world, parent/child]
---
# this is a heading
`
);
expect(noteA.tags).toEqual(new Set(['hello', 'world', 'parent/child']));
});
});
describe('parser plugins', () => {

View File

@@ -232,7 +232,7 @@ describe('Wikilinks', () => {
expect(graph.getAllConnections()[0]).toEqual({
source: noteA.uri,
target: noteB.uri,
link: expect.objectContaining({ type: 'wikilink', slug: 'page-b' }),
link: expect.objectContaining({ type: 'wikilink', label: 'page-b' }),
});
});
@@ -354,6 +354,51 @@ describe('Wikilinks', () => {
attachmentABis.uri,
]);
});
it('Allows for dendron-style wikilinks, including a dot', () => {
const noteA = createTestNote({
uri: '/path/to/page-a.md',
links: [{ slug: 'dendron.style' }],
});
const noteB1 = createTestNote({ uri: '/path/to/another/dendron.style.md' });
const ws = createTestWorkspace();
ws.set(noteA).set(noteB1);
const graph = FoamGraph.fromWorkspace(ws);
expect(graph.getLinks(noteA.uri).map(l => l.target)).toEqual([noteB1.uri]);
});
it('Handles capatalization of files and wiki links correctly', () => {
const noteA = createTestNote({
uri: '/path/to/page-a.md',
links: [
// uppercased filename, lowercased slug
{ slug: 'page-b' },
// lowercased filename, camelcased wikilink
{ slug: 'Page-C' },
// lowercased filename, lowercased wikilink
{ slug: 'page-d' },
],
});
const ws = createTestWorkspace()
.set(noteA)
.set(createTestNote({ uri: '/somewhere/PAGE-B.md' }))
.set(createTestNote({ uri: '/path/another/page-c.md' }))
.set(createTestNote({ uri: '/path/another/page-d.md' }));
const graph = FoamGraph.fromWorkspace(ws);
expect(
graph
.getLinks(noteA.uri)
.map(link => link.target.path)
.sort()
).toEqual([
'/path/another/page-c.md',
'/path/another/page-d.md',
'/somewhere/PAGE-B.md',
]);
});
});
describe('markdown direct links', () => {

View File

@@ -3741,9 +3741,9 @@ github-slugger@^1.3.0:
emoji-regex ">=6.0.0 <=6.1.1"
glob-parent@^5.0.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229"
integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==
version "5.1.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
dependencies:
is-glob "^4.0.1"
@@ -5924,6 +5924,11 @@ replace-ext@1.0.0:
resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb"
integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=
replace-ext@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-2.0.0.tgz#9471c213d22e1bcc26717cd6e50881d88f812b06"
integrity sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==
request-promise-core@1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.3.tgz#e9a3c081b51380dfea677336061fea879a829ee9"
@@ -7220,9 +7225,9 @@ write@1.0.3:
mkdirp "^0.5.1"
ws@^5.2.0:
version "5.2.2"
resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f"
integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==
version "5.2.3"
resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.3.tgz#05541053414921bc29c63bee14b8b0dd50b07b3d"
integrity sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA==
dependencies:
async-limiter "~1.0.0"

View File

@@ -4,6 +4,16 @@ All notable changes to the "foam-vscode" extension will be documented in this fi
Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.
## [0.13.8] - 2021-07-02
Fixes and Improvements:
- Improved handling of capitalization in wikilinks (#688 - thanks @pderaaij)
- This update will make wikilinks with different capitalization, such as `[[wikilink]]` and `[[WikiLink]]` point to the same file. Please note that means that files that only differ in capitalization across the workspace would now be treated as having the same name
- Allow dots in wikilinks (#689 - thanks @pderaaij)
- Fixed a bug in the expansion of date snippets (thanks @syndenham-chorea)
- Added support for wikilink alias syntax, like `[[wikilink|label]]` (#689 - thanks @pderaaij)
## [0.13.7] - 2021-06-05
Fixes and Improvements:

View File

@@ -8,7 +8,7 @@
"type": "git"
},
"homepage": "https://github.com/foambubble/foam",
"version": "0.13.7",
"version": "0.13.8",
"license": "MIT",
"publisher": "foam",
"engines": {
@@ -395,7 +395,7 @@
},
"dependencies": {
"dateformat": "^3.0.3",
"foam-core": "^0.13.7",
"foam-core": "^0.13.8",
"gray-matter": "^4.0.2",
"markdown-it-regex": "^0.2.0",
"micromatch": "^4.0.2",

View File

@@ -5,6 +5,14 @@ import { isAbsolute } from 'path';
import { docConfig, focusNote, pathExists } from './utils';
import { URI } from 'foam-core';
/**
* Open the daily note file.
*
* In the case that the daily note file does not exist,
* it gets created along with any folders in its path.
*
* @param date A given date to be formatted as filename.
*/
async function openDailyNoteFor(date?: Date) {
const foamConfiguration = workspace.getConfiguration('foam');
const currentDate = date !== undefined ? date : new Date();
@@ -19,6 +27,19 @@ async function openDailyNoteFor(date?: Date) {
await focusNote(dailyNotePath, isNew);
}
/**
* Get the daily note file path.
*
* This function first checks the `foam.openDailyNote.directory` configuration string,
* defaulting to the current directory.
*
* In the case that the directory path is not absolute,
* the resulting path will start on the current workspace top-level.
*
* @param configuration The current workspace configuration.
* @param date A given date to be formatted as filename.
* @returns The path to the daily note file.
*/
function getDailyNotePath(
configuration: WorkspaceConfiguration,
date: Date
@@ -38,6 +59,17 @@ function getDailyNotePath(
}
}
/**
* Get the daily note filename (basename) to use.
*
* Fetch the filename format and extension from
* `foam.openDailyNote.filenameFormat` and
* `foam.openDailyNote.fileExtension`, respectively.
*
* @param configuration The current workspace configuration.
* @param date A given date to be formatted as filename.
* @returns The daily note's filename.
*/
function getDailyNoteFileName(
configuration: WorkspaceConfiguration,
date: Date
@@ -52,6 +84,17 @@ function getDailyNoteFileName(
return `${dateFormat(date, filenameFormat, false)}.${fileExtension}`;
}
/**
* Create a daily note if it does not exist.
*
* In the case that the folders referenced in the file path also do not exist,
* this function will create all folders in the path.
*
* @param configuration The current workspace configuration.
* @param dailyNotePath The path to daily note file.
* @param currentDate The current date, to be used as a title.
* @returns Wether the file was created.
*/
async function createDailyNoteIfNotExists(
configuration: WorkspaceConfiguration,
dailyNotePath: URI,
@@ -77,6 +120,17 @@ async function createDailyNoteIfNotExists(
return true;
}
/**
* Create the directory (or directories) needed for the note to be placed in.
*
* If the daily note's folder does not exist,
* create such directory and all other non-existent directories in the path.
*
* For example, for the path `/home/user/foam-template/journal/yyyy-mm-dd.md`,
* it will create all directories in the path up until the file.
*
* @param dailyNotePath The path to the daily note file.
*/
async function createDailyNoteDirectoryIfNotExists(dailyNotePath: URI) {
const dailyNoteDirectory = URI.getDir(dailyNotePath);

View File

@@ -125,10 +125,7 @@ export class BacklinkTreeItem extends vscode.TreeItem {
public readonly resource: Resource,
public readonly link: ResourceLink
) {
super(
link.type === 'wikilink' ? link.slug : link.label,
vscode.TreeItemCollapsibleState.None
);
super(link.label, vscode.TreeItemCollapsibleState.None);
this.label = `${link.range.start.line}: ${this.label}`;
this.command = {
command: 'vscode.open',

View File

@@ -100,4 +100,24 @@ describe('Document links provider', () => {
);
expect(links[0].range).toEqual(new vscode.Range(0, 18, 0, 35));
});
it('should support wikilinks that have an alias', async () => {
const fileB = await createFile('# File B');
const fileA = await createFile(
`this is a link to [[${fileB.name}|alias]].`
);
const noteA = parser.parse(fileA.uri, fileA.content);
const noteB = parser.parse(fileB.uri, fileB.content);
const ws = createTestWorkspace()
.set(noteA)
.set(noteB);
const { doc } = await showInEditor(noteA.uri);
const provider = new LinkProvider(ws, parser);
const links = provider.provideDocumentLinks(doc);
expect(links.length).toEqual(1);
expect(links[0].target).toEqual(OPEN_COMMAND.asURI(noteB.uri));
expect(links[0].range).toEqual(new vscode.Range(0, 18, 0, 33));
});
});

View File

@@ -80,7 +80,7 @@ const getDailyNoteLink = (date: Date) => {
return `[[${name.replace(`.${foamExtension}`, '')}]]`;
};
const snippets: (() => DateSnippet)[] = [
const snippetFactories: (() => DateSnippet)[] = [
() => ({
detail: "Insert a link to today's daily note",
snippet: '/day',
@@ -169,24 +169,28 @@ const computedSnippets: ((number: number) => DateSnippet)[] = [
];
const completions: CompletionItemProvider = {
provideCompletionItems: (_document, _position, _token, _context) => {
provideCompletionItems: (document, position, _token, _context) => {
if (_context.triggerKind === CompletionTriggerKind.Invoke) {
// if completion was triggered without trigger character then we return [] to fallback
// to vscode word-based suggestions (see https://github.com/foambubble/foam/pull/417)
return [];
}
const range = document.getWordRangeAtPosition(position, /\S+/);
const completionItems = [
...snippets.map(item => createCompletionItem(item())),
...generateDayOfWeekSnippets().map(item => createCompletionItem(item)),
];
...snippetFactories.map(snippetFactory => snippetFactory()),
...generateDayOfWeekSnippets(),
].map(snippet => {
const completionItem = createCompletionItem(snippet);
completionItem.range = range;
return completionItem;
});
return completionItems;
},
};
const computedCompletions: CompletionItemProvider = {
provideCompletionItems: (document, position, _token, _context) => {
if (_context.triggerKind === CompletionTriggerKind.Invoke) {
export const datesCompletionProvider: CompletionItemProvider = {
provideCompletionItems: (document, position, _token, context) => {
if (context.triggerKind === CompletionTriggerKind.Invoke) {
// if completion was triggered without trigger character then we return [] to fallback
// to vscode word-based suggestions (see https://github.com/foambubble/foam/pull/417)
return [];
@@ -229,7 +233,7 @@ const feature: FoamFeature = {
languages.registerCompletionItemProvider('markdown', completions, '/');
languages.registerCompletionItemProvider(
'markdown',
computedCompletions,
datesCompletionProvider,
'/',
'+'
);

View File

@@ -1,7 +1,10 @@
import * as vscode from 'vscode';
import markdownItRegex from 'markdown-it-regex';
import { Foam, FoamWorkspace, Logger, URI } from 'foam-core';
import markdownItRegex from 'markdown-it-regex';
import * as vscode from 'vscode';
import { FoamFeature } from '../types';
import { isNone } from '../utils';
const ALIAS_DIVIDER_CHAR = '|';
const feature: FoamFeature = {
activate: async (
@@ -11,11 +14,13 @@ const feature: FoamFeature = {
const foam = await foamPromise;
return {
extendMarkdownIt: (md: markdownit) =>
[markdownItWithFoamTags, markdownItWithFoamLinks].reduce(
(acc, extension) => extension(acc, foam.workspace),
md
),
extendMarkdownIt: (md: markdownit) => {
return [
markdownItWithFoamTags,
markdownItWithFoamLinks,
markdownItWithRemoveLinkReferences,
].reduce((acc, extension) => extension(acc, foam.workspace), md);
},
};
},
};
@@ -29,13 +34,23 @@ export const markdownItWithFoamLinks = (
regex: /\[\[([^[\]]+?)\]\]/,
replace: (wikilink: string) => {
try {
const resource = workspace.find(wikilink);
if (resource == null) {
return getPlaceholderLink(wikilink);
const linkHasAlias = wikilink.includes(ALIAS_DIVIDER_CHAR);
const resourceLink = linkHasAlias
? wikilink.substring(0, wikilink.indexOf('|'))
: wikilink;
const resource = workspace.find(resourceLink);
if (isNone(resource)) {
return getPlaceholderLink(resourceLink);
}
const linkLabel = linkHasAlias
? wikilink.substr(wikilink.indexOf('|') + 1)
: wikilink;
return `<a class='foam-note-link' title='${
resource.title
}' href='${URI.toFsPath(resource.uri)}'>${wikilink}</a>`;
}' href='${URI.toFsPath(resource.uri)}'>${linkLabel}</a>`;
} catch (e) {
Logger.error(
`Error while creating link for [[${wikilink}]] in Preview panel`,
@@ -60,7 +75,7 @@ export const markdownItWithFoamTags = (
replace: (tag: string) => {
try {
const resource = workspace.find(tag);
if (resource == null) {
if (isNone(resource)) {
return getFoamTag(tag);
}
} catch (e) {
@@ -77,4 +92,16 @@ export const markdownItWithFoamTags = (
const getFoamTag = (content: string) =>
`<span class='foam-tag'>${content}</span>`;
export const markdownItWithRemoveLinkReferences = (
md: markdownit,
workspace: FoamWorkspace
) => {
// Forget about reference blocks before processing links.
md.inline.ruler.before('link', 'clear-references', state => {
state.env.references = undefined;
return false;
});
return md;
};
export default feature;

View File

@@ -70,10 +70,10 @@ export const createTestNote = (params: {
return 'slug' in link
? {
type: 'wikilink',
slug: link.slug,
target: link.slug,
label: link.slug,
range: range,
text: 'link text',
rawText: 'link text',
}
: {
type: 'link',
@@ -139,7 +139,7 @@ export const createNote = (r: Resource) => {
some content and ${r.links
.map(l =>
l.type === 'wikilink' ? `[[${l.slug}]]` : `[${l.label}](${l.target})`
l.type === 'wikilink' ? `[[${l.label}]]` : `[${l.label}](${l.target})`
)
.join(' some content between links.\n')}
last line.

View File

@@ -2506,10 +2506,10 @@
"resolved" "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz"
"version" "2.0.2"
"foam-core@^0.13.6":
"integrity" "sha512-Yu+ACWQ38EdTnGMuYRIVlqc6FzJfvm1GWM50w3Wnpx7w/AaUTnnlddCccnYzmXYiISZTRfWQgiOdR/0L9i3WJw=="
"resolved" "https://registry.npmjs.org/foam-core/-/foam-core-0.13.6.tgz"
"version" "0.13.6"
"foam-core@^0.13.7":
"integrity" "sha512-+A2RUGvkk1ntyrjhQkf0mUo1ytWrqWKYho56R4avCc9W1dQtavJ4+IGv+iR+ettAk8k5hbuF30KOZm4KCplhJA=="
"resolved" "https://registry.npmjs.org/foam-core/-/foam-core-0.13.7.tgz"
"version" "0.13.7"
dependencies:
"detect-newline" "^3.1.0"
"fast-array-diff" "^1.0.0"
@@ -2520,6 +2520,7 @@
"remark-frontmatter" "^2.0.0"
"remark-parse" "^8.0.2"
"remark-wiki-link" "^0.0.4"
"replace-ext" "^2.0.0"
"title-case" "^3.0.2"
"unified" "^9.0.0"
"unist-util-visit" "^2.0.2"
@@ -4459,6 +4460,11 @@
"resolved" "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz"
"version" "1.6.1"
"replace-ext@^2.0.0":
"integrity" "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug=="
"resolved" "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz"
"version" "2.0.0"
"replace-ext@1.0.0":
"integrity" "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs="
"resolved" "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz"

View File

@@ -5,7 +5,7 @@
👀*This is an early stage project under rapid development. For updates join the [Foam community Discord](https://foambubble.github.io/join-discord/g)! 💬*
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-75-orange.svg?style=flat-square)](#contributors-)
[![All Contributors](https://img.shields.io/badge/all_contributors-76-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->
[![Discord Chat](https://img.shields.io/discord/729975036148056075?color=748AD9&label=discord%20chat&style=flat-square)](https://foambubble.github.io/join-discord/g)
@@ -158,6 +158,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<td align="center"><a href="https://github.com/Barabazs"><img src="https://avatars.githubusercontent.com/u/31799121?v=4?s=60" width="60px;" alt=""/><br /><sub><b>Barabas</b></sub></a><br /><a href="https://github.com/foambubble/foam/commits?author=Barabazs" title="Code">💻</a></td>
<td align="center"><a href="http://enginveske@gmail.com"><img src="https://avatars.githubusercontent.com/u/43685404?v=4?s=60" width="60px;" alt=""/><br /><sub><b>Engincan VESKE</b></sub></a><br /><a href="https://github.com/foambubble/foam/commits?author=EngincanV" title="Documentation">📖</a></td>
<td align="center"><a href="http://www.paulderaaij.nl"><img src="https://avatars.githubusercontent.com/u/495374?v=4?s=60" width="60px;" alt=""/><br /><sub><b>Paul de Raaij</b></sub></a><br /><a href="https://github.com/foambubble/foam/commits?author=pderaaij" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/bronson"><img src="https://avatars.githubusercontent.com/u/1776?v=4?s=60" width="60px;" alt=""/><br /><sub><b>Scott Bronson</b></sub></a><br /><a href="https://github.com/foambubble/foam/commits?author=bronson" title="Documentation">📖</a></td>
</tr>
</table>

View File

@@ -5422,9 +5422,9 @@ has@^1.0.3:
function-bind "^1.1.1"
hosted-git-info@^2.1.4, hosted-git-info@^2.7.1:
version "2.8.8"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488"
integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==
version "2.8.9"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==
hosted-git-info@^4.0.0:
version "4.0.0"