mirror of
https://github.com/foambubble/foam.git
synced 2026-01-11 15:08:01 -05:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4195797024 | ||
|
|
fa405f5f65 | ||
|
|
4fd573b9e4 | ||
|
|
f613e1b9e2 | ||
|
|
0ada7d8e2c | ||
|
|
8b39bcdf16 | ||
|
|
6073dc246d | ||
|
|
5b671d59a8 | ||
|
|
8abea48b5c | ||
|
|
2eeb2e156b |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -9,3 +9,4 @@ dist
|
||||
docs/_site
|
||||
docs/.sass-cache
|
||||
docs/.jekyll-metadata
|
||||
.test-workspace
|
||||
|
||||
38
.vscode/launch.json
vendored
38
.vscode/launch.json
vendored
@@ -6,15 +6,20 @@
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "node",
|
||||
"name": "Debug Jest Tests",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"runtimeArgs": ["workspace", "foam-vscode", "run", "test"], // ${yarnWorkspaceName} is what we're missing
|
||||
"args": ["--runInBand"],
|
||||
"runtimeExecutable": "yarn",
|
||||
"console": "integratedTerminal",
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
"disableOptimisticBPs": true
|
||||
"args": [
|
||||
"${workspaceFolder}/packages/foam-vscode/.test-workspace",
|
||||
"--disable-extensions",
|
||||
"--disable-workspace-trust",
|
||||
"--extensionDevelopmentPath=${workspaceFolder}/packages/foam-vscode",
|
||||
"--extensionTestsPath=${workspaceFolder}/packages/foam-vscode/out/test/suite"
|
||||
],
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/packages/foam-vscode/out/**/*.js"
|
||||
],
|
||||
"preLaunchTask": "${defaultBuildTask}"
|
||||
},
|
||||
{
|
||||
"name": "Run VSCode Extension",
|
||||
@@ -24,8 +29,25 @@
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceFolder}/packages/foam-vscode"
|
||||
],
|
||||
"outFiles": ["${workspaceFolder}/packages/foam-vscode/out/**/*.js"],
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/packages/foam-vscode/out/**/*.js"
|
||||
],
|
||||
"preLaunchTask": "${defaultBuildTask}"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"name": "vscode-jest-tests",
|
||||
"request": "launch",
|
||||
"console": "integratedTerminal",
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
"disableOptimisticBPs": true,
|
||||
"cwd": "${workspaceFolder}/packages/foam-vscode",
|
||||
"runtimeExecutable": "yarn",
|
||||
"args": [
|
||||
"jest",
|
||||
"--runInBand",
|
||||
"--watchAll=false"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
@@ -24,9 +24,9 @@
|
||||
"prettier.requireConfig": true,
|
||||
"editor.formatOnSave": true,
|
||||
"editor.tabSize": 2,
|
||||
"jest.debugCodeLens.showWhenTestStateIn": ["fail", "unknown", "pass"],
|
||||
"jest.autoRun": "off",
|
||||
"jest.rootPath": "packages/foam-vscode",
|
||||
"jest.jestCommandLine": "yarn jest",
|
||||
"gitdoc.enabled": false,
|
||||
"jest.autoEnable": false,
|
||||
"jest.runAllTestsFirst": false,
|
||||
"search.mode": "reuseEditor"
|
||||
}
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
],
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true,
|
||||
"version": "0.17.1"
|
||||
"version": "0.17.2"
|
||||
}
|
||||
|
||||
0
packages/foam-vscode/.test-workspace/.keep
Normal file
0
packages/foam-vscode/.test-workspace/.keep
Normal 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.17.2] - 2021-12-22
|
||||
|
||||
Fixes and Improvements:
|
||||
- Improved support for wikilinks in titles (#878)
|
||||
- Use syntax injection for wikilinks (#876 - thanks @memeplex)
|
||||
- Fix when applying text edits in last line
|
||||
|
||||
Internal:
|
||||
- DX: Clean up of testing setup (#881 - thanks @memeplex)
|
||||
|
||||
## [0.17.1] - 2021-12-16
|
||||
|
||||
Fixes and Improvements:
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
["@babel/preset-env", { targets: { node: "current" } }],
|
||||
"@babel/preset-typescript"
|
||||
],
|
||||
plugins: [["@babel/plugin-transform-runtime", { helpers: false }]]
|
||||
};
|
||||
@@ -82,7 +82,7 @@ module.exports = {
|
||||
// moduleNameMapper: {},
|
||||
|
||||
// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
|
||||
// modulePathIgnorePatterns: [],
|
||||
modulePathIgnorePatterns: ['.vscode-test'],
|
||||
|
||||
// Activates notifications for test results
|
||||
// notify: false,
|
||||
@@ -91,7 +91,7 @@ module.exports = {
|
||||
// notifyMode: "failure-change",
|
||||
|
||||
// A preset that is used as a base for Jest's configuration
|
||||
// preset: undefined,
|
||||
preset: 'ts-jest',
|
||||
|
||||
// Run tests from one or more projects
|
||||
// projects: undefined,
|
||||
@@ -126,13 +126,13 @@ module.exports = {
|
||||
// setupFiles: [],
|
||||
|
||||
// A list of paths to modules that run some code to configure or set up the testing framework before each test
|
||||
// setupFilesAfterEnv: [],
|
||||
setupFilesAfterEnv: ['jest-extended'],
|
||||
|
||||
// A list of paths to snapshot serializer modules Jest should use for snapshot testing
|
||||
// snapshotSerializers: [],
|
||||
|
||||
// The test environment that will be used for testing
|
||||
testEnvironment: "node"
|
||||
testEnvironment: 'node',
|
||||
|
||||
// Options that will be passed to the testEnvironment
|
||||
// testEnvironmentOptions: {},
|
||||
@@ -152,7 +152,10 @@ module.exports = {
|
||||
// ],
|
||||
|
||||
// The regexp pattern or array of patterns that Jest uses to detect test files
|
||||
// testRegex: [],
|
||||
// This is overridden in every runCLI invocation but it's here as the default
|
||||
// for vscode-jest. We only want unit tests in the test explorer (sidebar),
|
||||
// since spec tests require the entire extension host to be launched before.
|
||||
testRegex: ['\\.test\\.ts$'],
|
||||
|
||||
// This option allows the use of a custom results processor
|
||||
// testResultsProcessor: undefined,
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"type": "git"
|
||||
},
|
||||
"homepage": "https://github.com/foambubble/foam",
|
||||
"version": "0.17.1",
|
||||
"version": "0.17.2",
|
||||
"license": "MIT",
|
||||
"publisher": "foam",
|
||||
"engines": {
|
||||
@@ -37,6 +37,26 @@
|
||||
"markdown.previewStyles": [
|
||||
"./static/preview/style.css"
|
||||
],
|
||||
"grammars": [
|
||||
{
|
||||
"path": "./syntaxes/injection.json",
|
||||
"scopeName": "foam.wikilink.injection",
|
||||
"injectTo": [
|
||||
"text.html.markdown"
|
||||
]
|
||||
}
|
||||
],
|
||||
"colors": [
|
||||
{
|
||||
"id": "foam.placeholder",
|
||||
"description": "Color of foam placeholders.",
|
||||
"defaults": {
|
||||
"dark": "editorWarning.foreground",
|
||||
"light": "editorWarning.foreground",
|
||||
"highContrast": "editorWarning.foreground"
|
||||
}
|
||||
}
|
||||
],
|
||||
"views": {
|
||||
"explorer": [
|
||||
{
|
||||
@@ -356,7 +376,9 @@
|
||||
"build": "tsc -p ./",
|
||||
"pretest": "yarn build",
|
||||
"test": "node ./out/test/run-tests.js",
|
||||
"pretest:unit": "yarn build",
|
||||
"test:unit": "node ./out/test/run-tests.js --unit",
|
||||
"pretest:e2e": "yarn build",
|
||||
"test:e2e": "node ./out/test/run-tests.js --e2e",
|
||||
"lint": "tsdx lint src",
|
||||
"clean": "rimraf out",
|
||||
@@ -377,7 +399,6 @@
|
||||
"@babel/preset-env": "^7.11.0",
|
||||
"@babel/preset-typescript": "^7.10.4",
|
||||
"@types/dateformat": "^3.0.1",
|
||||
"@types/github-slugger": "^1.3.0",
|
||||
"@types/glob": "^7.1.1",
|
||||
"@types/lodash": "^4.14.157",
|
||||
"@types/markdown-it": "^12.0.1",
|
||||
@@ -388,12 +409,10 @@
|
||||
"@types/vscode": "^1.47.1",
|
||||
"@typescript-eslint/eslint-plugin": "^2.30.0",
|
||||
"@typescript-eslint/parser": "^2.30.0",
|
||||
"babel-jest": "^26.2.2",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-plugin-import": "^2.24.2",
|
||||
"husky": "^4.2.5",
|
||||
"jest": "^26.2.2",
|
||||
"jest-environment-vscode": "^1.0.0",
|
||||
"jest-extended": "^0.11.5",
|
||||
"markdown-it": "^12.0.4",
|
||||
"rimraf": "^3.0.2",
|
||||
@@ -407,7 +426,6 @@
|
||||
"dateformat": "^3.0.3",
|
||||
"detect-newline": "^3.1.0",
|
||||
"fast-array-diff": "^1.0.1",
|
||||
"github-slugger": "^1.3.0",
|
||||
"glob": "^7.1.6",
|
||||
"gray-matter": "^4.0.2",
|
||||
"lodash": "^4.17.21",
|
||||
|
||||
@@ -34,5 +34,5 @@ const getOffset = (
|
||||
offset = offset + lines[i].length + eolLen;
|
||||
i++;
|
||||
}
|
||||
return offset + Math.min(position.character, lines[i].length);
|
||||
return offset + Math.min(position.character, lines[i]?.length ?? 0);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import GithubSlugger from 'github-slugger';
|
||||
import { Resource } from '../model/note';
|
||||
import { Range } from '../model/range';
|
||||
import {
|
||||
@@ -7,13 +6,10 @@ import {
|
||||
} from '../markdown-provider';
|
||||
import { getHeadingFromFileName } from '../utils';
|
||||
import { FoamWorkspace } from '../model/workspace';
|
||||
import { uriToSlug } from '../utils/slug';
|
||||
|
||||
export const LINK_REFERENCE_DEFINITION_HEADER = `[//begin]: # "Autogenerated link references for markdown compatibility"`;
|
||||
export const LINK_REFERENCE_DEFINITION_FOOTER = `[//end]: # "Autogenerated link references"`;
|
||||
|
||||
const slugger = new GithubSlugger();
|
||||
|
||||
export interface TextEdit {
|
||||
range: Range;
|
||||
newText: string;
|
||||
@@ -168,7 +164,7 @@ export const generateHeading = (note: Resource): TextEdit | null => {
|
||||
|
||||
return {
|
||||
newText: `${paddingStart}# ${getHeadingFromFileName(
|
||||
uriToSlug(note.uri)
|
||||
note.uri.getName()
|
||||
)}${paddingEnd}`,
|
||||
range: Range.createFromPosition(
|
||||
note.source.contentStart,
|
||||
@@ -176,14 +172,3 @@ export const generateHeading = (note: Resource): TextEdit | null => {
|
||||
),
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param fileName
|
||||
* @returns null if file name is already in kebab case otherise returns
|
||||
* the kebab cased file name
|
||||
*/
|
||||
export const getKebabCaseFileName = (fileName: string) => {
|
||||
const kebabCasedFileName = slugger.slug(fileName);
|
||||
return kebabCasedFileName === fileName ? null : kebabCasedFileName;
|
||||
};
|
||||
|
||||
@@ -5,11 +5,10 @@ import {
|
||||
} from './markdown-provider';
|
||||
import { DirectLink, WikiLink } from './model/note';
|
||||
import { Logger } from './utils/log';
|
||||
import { uriToSlug } from './utils/slug';
|
||||
import { URI } from './model/uri';
|
||||
import { FoamGraph } from './model/graph';
|
||||
import { Range } from './model/range';
|
||||
import { createTestWorkspace } from '../test/test-utils';
|
||||
import { createTestWorkspace, getRandomURI } from '../test/test-utils';
|
||||
|
||||
Logger.setLevel('error');
|
||||
|
||||
@@ -40,50 +39,45 @@ const pageE = `
|
||||
# Page E
|
||||
`;
|
||||
|
||||
const createNoteFromMarkdown = (path: string, content: string) =>
|
||||
createMarkdownParser([]).parse(URI.file(path), content);
|
||||
const createNoteFromMarkdown = (content: string, path?: string) =>
|
||||
createMarkdownParser([]).parse(
|
||||
path ? URI.file(path) : getRandomURI(),
|
||||
content
|
||||
);
|
||||
|
||||
describe('Markdown loader', () => {
|
||||
it('Converts markdown to notes', () => {
|
||||
const workspace = createTestWorkspace();
|
||||
workspace.set(createNoteFromMarkdown('/page-a.md', pageA));
|
||||
workspace.set(createNoteFromMarkdown('/page-b.md', pageB));
|
||||
workspace.set(createNoteFromMarkdown('/page-c.md', pageC));
|
||||
workspace.set(createNoteFromMarkdown('/page-d.md', pageD));
|
||||
workspace.set(createNoteFromMarkdown('/page-e.md', pageE));
|
||||
workspace.set(createNoteFromMarkdown(pageA, '/page-a.md'));
|
||||
workspace.set(createNoteFromMarkdown(pageB, '/page-b.md'));
|
||||
workspace.set(createNoteFromMarkdown(pageC, '/page-c.md'));
|
||||
workspace.set(createNoteFromMarkdown(pageD, '/page-d.md'));
|
||||
workspace.set(createNoteFromMarkdown(pageE, '/page-e.md'));
|
||||
|
||||
expect(
|
||||
workspace
|
||||
.list()
|
||||
.map(n => n.uri)
|
||||
.map(uriToSlug)
|
||||
.map(n => n.uri.getName())
|
||||
.sort()
|
||||
).toEqual(['page-a', 'page-b', 'page-c', 'page-d', 'page-e']);
|
||||
});
|
||||
|
||||
it('Ingores external links', () => {
|
||||
const note = createNoteFromMarkdown(
|
||||
'/path/to/page-a.md',
|
||||
`
|
||||
this is a [link to google](https://www.google.com)
|
||||
`
|
||||
`this is a [link to google](https://www.google.com)`
|
||||
);
|
||||
expect(note.links.length).toEqual(0);
|
||||
});
|
||||
|
||||
it('Ignores references to sections in the same file', () => {
|
||||
const note = createNoteFromMarkdown(
|
||||
'/path/to/page-a.md',
|
||||
`
|
||||
this is a [link to intro](#introduction)
|
||||
`
|
||||
`this is a [link to intro](#introduction)`
|
||||
);
|
||||
expect(note.links.length).toEqual(0);
|
||||
});
|
||||
|
||||
it('Parses internal links correctly', () => {
|
||||
const note = createNoteFromMarkdown(
|
||||
'/path/to/page-a.md',
|
||||
'this is a [link to page b](../doc/page-b.md)'
|
||||
);
|
||||
expect(note.links.length).toEqual(1);
|
||||
@@ -95,7 +89,6 @@ this is a [link to intro](#introduction)
|
||||
|
||||
it('Parses links that have formatting in label', () => {
|
||||
const note = createNoteFromMarkdown(
|
||||
'/path/to/page-a.md',
|
||||
'this is [**link** with __formatting__](../doc/page-b.md)'
|
||||
);
|
||||
expect(note.links.length).toEqual(1);
|
||||
@@ -107,11 +100,11 @@ this is a [link to intro](#introduction)
|
||||
|
||||
it('Parses wikilinks correctly', () => {
|
||||
const workspace = createTestWorkspace();
|
||||
const noteA = createNoteFromMarkdown('/page-a.md', pageA);
|
||||
const noteB = createNoteFromMarkdown('/page-b.md', pageB);
|
||||
const noteC = createNoteFromMarkdown('/page-c.md', pageC);
|
||||
const noteD = createNoteFromMarkdown('/Page D.md', pageD);
|
||||
const noteE = createNoteFromMarkdown('/page e.md', pageE);
|
||||
const noteA = createNoteFromMarkdown(pageA, '/page-a.md');
|
||||
const noteB = createNoteFromMarkdown(pageB, '/page-b.md');
|
||||
const noteC = createNoteFromMarkdown(pageC, '/page-c.md');
|
||||
const noteD = createNoteFromMarkdown(pageD, '/Page D.md');
|
||||
const noteE = createNoteFromMarkdown(pageE, '/page e.md');
|
||||
|
||||
workspace
|
||||
.set(noteA)
|
||||
@@ -134,7 +127,6 @@ this is a [link to intro](#introduction)
|
||||
|
||||
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);
|
||||
@@ -151,9 +143,7 @@ this is a [link to intro](#introduction)
|
||||
});
|
||||
|
||||
it('Skips wikilinks in codeblocks', () => {
|
||||
const noteA = createNoteFromMarkdown(
|
||||
'/dir1/page-a.md',
|
||||
`
|
||||
const noteA = createNoteFromMarkdown(`
|
||||
this is some text with our [[first-wikilink]].
|
||||
|
||||
\`\`\`
|
||||
@@ -161,8 +151,7 @@ this is inside a [[codeblock]]
|
||||
\`\`\`
|
||||
|
||||
this is some text with our [[second-wikilink]].
|
||||
`
|
||||
);
|
||||
`);
|
||||
expect(noteA.links.map(l => l.label)).toEqual([
|
||||
'first-wikilink',
|
||||
'second-wikilink',
|
||||
@@ -170,16 +159,13 @@ this is some text with our [[second-wikilink]].
|
||||
});
|
||||
|
||||
it('Skips wikilinks in inlined codeblocks', () => {
|
||||
const noteA = createNoteFromMarkdown(
|
||||
'/dir1/page-a.md',
|
||||
`
|
||||
const noteA = createNoteFromMarkdown(`
|
||||
this is some text with our [[first-wikilink]].
|
||||
|
||||
this is \`inside a [[codeblock]]\`
|
||||
|
||||
this is some text with our [[second-wikilink]].
|
||||
`
|
||||
);
|
||||
`);
|
||||
expect(noteA.links.map(l => l.label)).toEqual([
|
||||
'first-wikilink',
|
||||
'second-wikilink',
|
||||
@@ -189,71 +175,71 @@ this is some text with our [[second-wikilink]].
|
||||
|
||||
describe('Note Title', () => {
|
||||
it('should initialize note title if heading exists', () => {
|
||||
const note = createNoteFromMarkdown(
|
||||
'/page-a.md',
|
||||
`
|
||||
const note = createNoteFromMarkdown(`
|
||||
# Page A
|
||||
this note has a title
|
||||
`
|
||||
);
|
||||
`);
|
||||
expect(note.title).toBe('Page A');
|
||||
});
|
||||
|
||||
it('should support wikilinks and urls in title', () => {
|
||||
const note = createNoteFromMarkdown(`
|
||||
# Page A with [[wikilink]] and a [url](https://google.com)
|
||||
this note has a title
|
||||
`);
|
||||
expect(note.title).toBe('Page A with wikilink and a url');
|
||||
});
|
||||
|
||||
it('should default to file name if heading does not exist', () => {
|
||||
const note = createNoteFromMarkdown(
|
||||
'/page-d.md',
|
||||
`
|
||||
This file has no heading.
|
||||
`
|
||||
`This file has no heading.`,
|
||||
'/page-d.md'
|
||||
);
|
||||
|
||||
expect(note.title).toEqual('page-d');
|
||||
});
|
||||
|
||||
it('should give precedence to frontmatter title over other headings', () => {
|
||||
const note = createNoteFromMarkdown(
|
||||
'/page-e.md',
|
||||
`
|
||||
const note = createNoteFromMarkdown(`
|
||||
---
|
||||
title: Note Title
|
||||
date: 20-12-12
|
||||
---
|
||||
|
||||
# Other Note Title
|
||||
`
|
||||
);
|
||||
`);
|
||||
|
||||
expect(note.title).toBe('Note Title');
|
||||
});
|
||||
|
||||
it('should support numbers', () => {
|
||||
const note1 = createNoteFromMarkdown('/157.md', `hello`);
|
||||
const note1 = createNoteFromMarkdown(`hello`, '/157.md');
|
||||
expect(note1.title).toBe('157');
|
||||
|
||||
const note2 = createNoteFromMarkdown('/157.md', `# 158`);
|
||||
const note2 = createNoteFromMarkdown(`# 158`, '/157.md');
|
||||
expect(note2.title).toBe('158');
|
||||
|
||||
const note3 = createNoteFromMarkdown(
|
||||
'/157.md',
|
||||
`
|
||||
---
|
||||
title: 159
|
||||
---
|
||||
|
||||
# 158
|
||||
`
|
||||
`,
|
||||
'/157.md'
|
||||
);
|
||||
expect(note3.title).toBe('159');
|
||||
});
|
||||
|
||||
it('should not break on empty titles (see #276)', () => {
|
||||
const note = createNoteFromMarkdown(
|
||||
'/Hello Page.md',
|
||||
`
|
||||
#
|
||||
|
||||
this note has an empty title line
|
||||
`
|
||||
`,
|
||||
'/Hello Page.md'
|
||||
);
|
||||
expect(note.title).toEqual('Hello Page');
|
||||
});
|
||||
@@ -261,47 +247,38 @@ this note has an empty title line
|
||||
|
||||
describe('frontmatter', () => {
|
||||
it('should parse yaml frontmatter', () => {
|
||||
const note = createNoteFromMarkdown(
|
||||
'/page-e.md',
|
||||
`
|
||||
const note = createNoteFromMarkdown(`
|
||||
---
|
||||
title: Note Title
|
||||
date: 20-12-12
|
||||
---
|
||||
|
||||
# Other Note Title`
|
||||
);
|
||||
# Other Note Title`);
|
||||
|
||||
expect(note.properties.title).toBe('Note Title');
|
||||
expect(note.properties.date).toBe('20-12-12');
|
||||
});
|
||||
|
||||
it('should parse empty frontmatter', () => {
|
||||
const note = createNoteFromMarkdown(
|
||||
'/page-f.md',
|
||||
`
|
||||
const note = createNoteFromMarkdown(`
|
||||
---
|
||||
---
|
||||
|
||||
# Empty Frontmatter
|
||||
`
|
||||
);
|
||||
`);
|
||||
|
||||
expect(note.properties).toEqual({});
|
||||
});
|
||||
|
||||
it('should not fail when there are issues with parsing frontmatter', () => {
|
||||
const note = createNoteFromMarkdown(
|
||||
'/page-f.md',
|
||||
`
|
||||
const note = createNoteFromMarkdown(`
|
||||
---
|
||||
title: - one
|
||||
- two
|
||||
- #
|
||||
---
|
||||
|
||||
`
|
||||
);
|
||||
`);
|
||||
|
||||
expect(note.properties).toEqual({});
|
||||
});
|
||||
@@ -310,11 +287,11 @@ title: - one
|
||||
describe('wikilinks definitions', () => {
|
||||
it('can generate links without file extension when includeExtension = false', () => {
|
||||
const workspace = createTestWorkspace();
|
||||
const noteA = createNoteFromMarkdown('/dir1/page-a.md', pageA);
|
||||
const noteA = createNoteFromMarkdown(pageA, '/dir1/page-a.md');
|
||||
workspace
|
||||
.set(noteA)
|
||||
.set(createNoteFromMarkdown('/dir1/page-b.md', pageB))
|
||||
.set(createNoteFromMarkdown('/dir1/page-c.md', pageC));
|
||||
.set(createNoteFromMarkdown(pageB, '/dir1/page-b.md'))
|
||||
.set(createNoteFromMarkdown(pageC, '/dir1/page-c.md'));
|
||||
|
||||
const noExtRefs = createMarkdownReferences(workspace, noteA.uri, false);
|
||||
expect(noExtRefs.map(r => r.url)).toEqual(['page-b', 'page-c']);
|
||||
@@ -322,11 +299,11 @@ describe('wikilinks definitions', () => {
|
||||
|
||||
it('can generate links with file extension when includeExtension = true', () => {
|
||||
const workspace = createTestWorkspace();
|
||||
const noteA = createNoteFromMarkdown('/dir1/page-a.md', pageA);
|
||||
const noteA = createNoteFromMarkdown(pageA, '/dir1/page-a.md');
|
||||
workspace
|
||||
.set(noteA)
|
||||
.set(createNoteFromMarkdown('/dir1/page-b.md', pageB))
|
||||
.set(createNoteFromMarkdown('/dir1/page-c.md', pageC));
|
||||
.set(createNoteFromMarkdown(pageB, '/dir1/page-b.md'))
|
||||
.set(createNoteFromMarkdown(pageC, '/dir1/page-c.md'));
|
||||
|
||||
const extRefs = createMarkdownReferences(workspace, noteA.uri, true);
|
||||
expect(extRefs.map(r => r.url)).toEqual(['page-b.md', 'page-c.md']);
|
||||
@@ -334,11 +311,11 @@ describe('wikilinks definitions', () => {
|
||||
|
||||
it('use relative paths', () => {
|
||||
const workspace = createTestWorkspace();
|
||||
const noteA = createNoteFromMarkdown('/dir1/page-a.md', pageA);
|
||||
const noteA = createNoteFromMarkdown(pageA, '/dir1/page-a.md');
|
||||
workspace
|
||||
.set(noteA)
|
||||
.set(createNoteFromMarkdown('/dir2/page-b.md', pageB))
|
||||
.set(createNoteFromMarkdown('/dir3/page-c.md', pageC));
|
||||
.set(createNoteFromMarkdown(pageB, '/dir2/page-b.md'))
|
||||
.set(createNoteFromMarkdown(pageC, '/dir3/page-c.md'));
|
||||
|
||||
const extRefs = createMarkdownReferences(workspace, noteA.uri, true);
|
||||
expect(extRefs.map(r => r.url)).toEqual([
|
||||
@@ -350,13 +327,10 @@ describe('wikilinks definitions', () => {
|
||||
|
||||
describe('tags plugin', () => {
|
||||
it('can find tags in the text of the note', () => {
|
||||
const noteA = createNoteFromMarkdown(
|
||||
'/dir1/page-a.md',
|
||||
`
|
||||
const noteA = createNoteFromMarkdown(`
|
||||
# this is a #heading
|
||||
#this is some #text that includes #tags we #care-about.
|
||||
`
|
||||
);
|
||||
`);
|
||||
expect(noteA.tags).toEqual([
|
||||
{ label: 'heading', range: Range.create(1, 12, 1, 20) },
|
||||
{ label: 'this', range: Range.create(2, 0, 2, 5) },
|
||||
@@ -367,16 +341,13 @@ describe('tags plugin', () => {
|
||||
});
|
||||
|
||||
it('will skip tags in codeblocks', () => {
|
||||
const noteA = createNoteFromMarkdown(
|
||||
'/dir1/page-a.md',
|
||||
`
|
||||
const noteA = createNoteFromMarkdown(`
|
||||
this is some #text that includes #tags we #care-about.
|
||||
|
||||
\`\`\`
|
||||
this is a #codeblock
|
||||
\`\`\`
|
||||
`
|
||||
);
|
||||
`);
|
||||
expect(noteA.tags.map(t => t.label)).toEqual([
|
||||
'text',
|
||||
'tags',
|
||||
@@ -385,13 +356,9 @@ this is a #codeblock
|
||||
});
|
||||
|
||||
it('will skip tags in inlined codeblocks', () => {
|
||||
const noteA = createNoteFromMarkdown(
|
||||
'/dir1/page-a.md',
|
||||
`
|
||||
const noteA = createNoteFromMarkdown(`
|
||||
this is some #text that includes #tags we #care-about.
|
||||
this is a \`inlined #codeblock\`
|
||||
`
|
||||
);
|
||||
this is a \`inlined #codeblock\` `);
|
||||
expect(noteA.tags.map(t => t.label)).toEqual([
|
||||
'text',
|
||||
'tags',
|
||||
@@ -399,16 +366,13 @@ this is a \`inlined #codeblock\`
|
||||
]);
|
||||
});
|
||||
it('can find tags as text in yaml', () => {
|
||||
const noteA = createNoteFromMarkdown(
|
||||
'/dir1/page-a.md',
|
||||
`
|
||||
const noteA = createNoteFromMarkdown(`
|
||||
---
|
||||
tags: hello, world this_is_good
|
||||
---
|
||||
# this is a heading
|
||||
this is some #text that includes #tags we #care-about.
|
||||
`
|
||||
);
|
||||
`);
|
||||
expect(noteA.tags.map(t => t.label)).toEqual([
|
||||
'hello',
|
||||
'world',
|
||||
@@ -420,16 +384,13 @@ this is some #text that includes #tags we #care-about.
|
||||
});
|
||||
|
||||
it('can find tags as array in yaml', () => {
|
||||
const noteA = createNoteFromMarkdown(
|
||||
'/dir1/page-a.md',
|
||||
`
|
||||
const noteA = createNoteFromMarkdown(`
|
||||
---
|
||||
tags: [hello, world, this_is_good]
|
||||
---
|
||||
# this is a heading
|
||||
this is some #text that includes #tags we #care-about.
|
||||
`
|
||||
);
|
||||
`);
|
||||
expect(noteA.tags.map(t => t.label)).toEqual([
|
||||
'hello',
|
||||
'world',
|
||||
@@ -444,16 +405,13 @@ this is some #text that includes #tags we #care-about.
|
||||
// For now it's enough to just get the YAML block range
|
||||
// in the future we might want to be more specific
|
||||
|
||||
const noteA = createNoteFromMarkdown(
|
||||
'/dir1/page-a.md',
|
||||
`
|
||||
const noteA = createNoteFromMarkdown(`
|
||||
---
|
||||
tags: [hello, world, this_is_good]
|
||||
---
|
||||
# this is a heading
|
||||
this is some text
|
||||
`
|
||||
);
|
||||
`);
|
||||
expect(noteA.tags[0]).toEqual({
|
||||
label: 'hello',
|
||||
range: Range.create(1, 0, 3, 3),
|
||||
@@ -463,9 +421,7 @@ this is some text
|
||||
|
||||
describe('Sections plugin', () => {
|
||||
it('should find sections within the note', () => {
|
||||
const note = createNoteFromMarkdown(
|
||||
'/dir1/page-a.md',
|
||||
`
|
||||
const note = createNoteFromMarkdown(`
|
||||
# Section 1
|
||||
|
||||
This is the content of section 1.
|
||||
@@ -477,8 +433,7 @@ This is the content of section 1.1.
|
||||
# Section 2
|
||||
|
||||
This is the content of section 2.
|
||||
`
|
||||
);
|
||||
`);
|
||||
expect(note.sections).toHaveLength(3);
|
||||
expect(note.sections[0].label).toEqual('Section 1');
|
||||
expect(note.sections[0].range).toEqual(Range.create(1, 0, 9, 0));
|
||||
@@ -487,6 +442,20 @@ This is the content of section 2.
|
||||
expect(note.sections[2].label).toEqual('Section 2');
|
||||
expect(note.sections[2].range).toEqual(Range.create(9, 0, 13, 0));
|
||||
});
|
||||
|
||||
it('should support wikilinks and links in the section label', () => {
|
||||
const note = createNoteFromMarkdown(`
|
||||
# Section with [[wikilink]]
|
||||
|
||||
This is the content of section with wikilink
|
||||
|
||||
## Section with [url](https://google.com)
|
||||
|
||||
This is the content of section with url`);
|
||||
expect(note.sections).toHaveLength(2);
|
||||
expect(note.sections[0].label).toEqual('Section with wikilink');
|
||||
expect(note.sections[1].label).toEqual('Section with url');
|
||||
});
|
||||
});
|
||||
|
||||
describe('parser plugins', () => {
|
||||
|
||||
@@ -177,9 +177,9 @@ export class MarkdownResourceProvider implements ResourceProvider {
|
||||
*/
|
||||
const getTextFromChildren = (root: Node): string => {
|
||||
let text = '';
|
||||
visit(root, 'text', node => {
|
||||
if (node.type === 'text') {
|
||||
text = text + (node as any).value;
|
||||
visit(root, node => {
|
||||
if (node.type === 'text' || node.type === 'wikiLink') {
|
||||
text = text + ((node as any).value || '');
|
||||
}
|
||||
});
|
||||
return text;
|
||||
@@ -226,7 +226,7 @@ const sectionsPlugin: ParserPlugin = {
|
||||
visit: (node, note) => {
|
||||
if (node.type === 'heading') {
|
||||
const level = (node as any).depth;
|
||||
const label = ((node as Parent)!.children?.[0] as any)?.value;
|
||||
const label = getTextFromChildren(node);
|
||||
if (!label || !level) {
|
||||
return;
|
||||
}
|
||||
@@ -272,8 +272,8 @@ const titlePlugin: ParserPlugin = {
|
||||
node.type === 'heading' &&
|
||||
(node as any).depth === 1
|
||||
) {
|
||||
note.title =
|
||||
((node as Parent)!.children?.[0] as any)?.value || note.title;
|
||||
const title = getTextFromChildren(node);
|
||||
note.title = title.length > 0 ? title : note.title;
|
||||
}
|
||||
},
|
||||
onDidFindProperties: (props, note) => {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Logger } from '../utils/log';
|
||||
import { uriToSlug } from '../utils/slug';
|
||||
import { URI } from './uri';
|
||||
|
||||
Logger.setLevel('error');
|
||||
@@ -73,16 +72,4 @@ describe('Foam URI', () => {
|
||||
URI.file('/hello.markdown')
|
||||
);
|
||||
});
|
||||
|
||||
it('can be slugified', () => {
|
||||
expect(uriToSlug(URI.file('/this/is/a/path.md'))).toEqual('path');
|
||||
expect(uriToSlug(URI.file('../a/relative/path.md'))).toEqual('path');
|
||||
expect(uriToSlug(URI.file('another/relative/path.md'))).toEqual('path');
|
||||
expect(uriToSlug(URI.file('no-directory.markdown'))).toEqual(
|
||||
'no-directory'
|
||||
);
|
||||
expect(uriToSlug(URI.file('many.dots.name.markdown'))).toEqual(
|
||||
'manydotsname'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
import GithubSlugger from 'github-slugger';
|
||||
import { URI } from '../model/uri';
|
||||
|
||||
export const uriToSlug = (uri: URI): string =>
|
||||
GithubSlugger.slug(uri.getName());
|
||||
@@ -8,21 +8,15 @@ import {
|
||||
import { ResourceParser } from '../core/model/note';
|
||||
import { FoamWorkspace } from '../core/model/workspace';
|
||||
import { Foam } from '../core/model/foam';
|
||||
import { Range } from '../core/model/range';
|
||||
import { fromVsCodeUri } from '../utils/vsc-utils';
|
||||
|
||||
export const CONFIG_KEY = 'decorations.links.enable';
|
||||
|
||||
const linkDecoration = vscode.window.createTextEditorDecorationType({
|
||||
rangeBehavior: vscode.DecorationRangeBehavior.ClosedClosed,
|
||||
textDecoration: 'none',
|
||||
color: { id: 'textLink.foreground' },
|
||||
cursor: 'pointer',
|
||||
});
|
||||
|
||||
const placeholderDecoration = vscode.window.createTextEditorDecorationType({
|
||||
rangeBehavior: vscode.DecorationRangeBehavior.ClosedClosed,
|
||||
textDecoration: 'none',
|
||||
color: { id: 'editorWarning.foreground' },
|
||||
color: { id: 'foam.placeholder' },
|
||||
cursor: 'pointer',
|
||||
});
|
||||
|
||||
@@ -42,17 +36,20 @@ const updateDecorations = (
|
||||
fromVsCodeUri(editor.document.uri),
|
||||
editor.document.getText()
|
||||
);
|
||||
let linkRanges = [];
|
||||
let placeholderRanges = [];
|
||||
note.links.forEach(link => {
|
||||
const linkUri = workspace.resolveLink(note, link);
|
||||
if (linkUri.isPlaceholder()) {
|
||||
placeholderRanges.push(link.range);
|
||||
} else {
|
||||
linkRanges.push(link.range);
|
||||
placeholderRanges.push(
|
||||
Range.create(
|
||||
link.range.start.line,
|
||||
link.range.start.character + 2,
|
||||
link.range.end.line,
|
||||
link.range.end.character - 2
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
editor.setDecorations(linkDecoration, linkRanges);
|
||||
editor.setDecorations(placeholderDecoration, placeholderRanges);
|
||||
};
|
||||
|
||||
@@ -82,7 +79,6 @@ const feature: FoamFeature = {
|
||||
|
||||
context.subscriptions.push(
|
||||
areDecorationsEnabled,
|
||||
linkDecoration,
|
||||
placeholderDecoration,
|
||||
vscode.window.onDidChangeActiveTextEditor(editor => {
|
||||
activeEditor = editor;
|
||||
|
||||
@@ -69,7 +69,7 @@ describe('Document navigation', () => {
|
||||
|
||||
expect(links.length).toEqual(1);
|
||||
expect(links[0].target).toEqual(OPEN_COMMAND.asURI(fileA.uri));
|
||||
expect(links[0].range).toEqual(new vscode.Range(0, 18, 0, 28));
|
||||
expect(links[0].range).toEqual(new vscode.Range(0, 20, 0, 26));
|
||||
});
|
||||
|
||||
it('should create links for placeholders', async () => {
|
||||
@@ -87,7 +87,7 @@ describe('Document navigation', () => {
|
||||
expect(links[0].target).toEqual(
|
||||
OPEN_COMMAND.asURI(URI.placeholder('a placeholder'))
|
||||
);
|
||||
expect(links[0].range).toEqual(new vscode.Range(0, 18, 0, 35));
|
||||
expect(links[0].range).toEqual(new vscode.Range(0, 20, 0, 33));
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -156,7 +156,12 @@ export class NavigationProvider
|
||||
return targets.map(o => {
|
||||
const command = OPEN_COMMAND.asURI(o.target);
|
||||
const documentLink = new vscode.DocumentLink(
|
||||
toVsCodeRange(o.link.range),
|
||||
new vscode.Range(
|
||||
o.link.range.start.line,
|
||||
o.link.range.start.character + 2,
|
||||
o.link.range.end.line,
|
||||
o.link.range.end.character - 2
|
||||
),
|
||||
command
|
||||
);
|
||||
documentLink.tooltip = o.target.isPlaceholder()
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import fs from 'fs';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import { runTests } from 'vscode-test';
|
||||
import { runUnit } from './suite-unit';
|
||||
@@ -35,23 +33,17 @@ async function main() {
|
||||
// The path to the extension test script
|
||||
// Passed to --extensionTestsPath
|
||||
const extensionTestsPath = path.join(__dirname, 'suite');
|
||||
const tmpWorkspaceDir = fs.mkdtempSync(path.join(os.tmpdir(), 'foam-'));
|
||||
|
||||
// Download VS Code, unzip it and run the integration test
|
||||
await runTests({
|
||||
extensionDevelopmentPath,
|
||||
extensionTestsPath,
|
||||
launchArgs: [
|
||||
tmpWorkspaceDir,
|
||||
path.join(extensionDevelopmentPath, '.test-workspace'),
|
||||
'--disable-extensions',
|
||||
'--disable-workspace-trust',
|
||||
],
|
||||
// Running the tests with vscode 1.53.0 is causing issues in the output/error stream management,
|
||||
// which is causing a stack overflow, possibly due to a recursive callback.
|
||||
// Also see https://github.com/foambubble/foam/pull/479#issuecomment-774167127
|
||||
// Forcing the version to 1.52.0 solves the problem.
|
||||
// TODO: to review, further investigate, and roll back this workaround.
|
||||
version: '1.52.0',
|
||||
version: '1.60.0',
|
||||
});
|
||||
} catch (err) {
|
||||
console.log('Error occurred while running Foam e2e tests:', err);
|
||||
|
||||
@@ -8,32 +8,28 @@
|
||||
* they will make direct use of the vscode API to be invoked as commands, create editors,
|
||||
* and so on..
|
||||
*/
|
||||
|
||||
/* eslint-disable import/first */
|
||||
|
||||
// Set before imports, see https://github.com/facebook/jest/issues/12162
|
||||
process.env.FORCE_COLOR = '1';
|
||||
process.env.NODE_ENV = 'test';
|
||||
|
||||
import path from 'path';
|
||||
import { runCLI } from '@jest/core';
|
||||
|
||||
const rootDir = path.join(__dirname, '..', '..');
|
||||
|
||||
export function runUnit(): Promise<void> {
|
||||
process.env.FORCE_COLOR = '1';
|
||||
process.env.NODE_ENV = 'test';
|
||||
process.env.BABEL_ENV = 'test';
|
||||
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
const { results } = await runCLI(
|
||||
{
|
||||
rootDir,
|
||||
roots: ['<rootDir>/src'],
|
||||
transform: JSON.stringify({ '^.+\\.ts$': 'ts-jest' }),
|
||||
runInBand: true,
|
||||
testRegex: '\\.(test)\\.ts$',
|
||||
setupFiles: ['<rootDir>/src/test/support/jest-setup.ts'],
|
||||
setupFilesAfterEnv: ['jest-extended'],
|
||||
globals: JSON.stringify({
|
||||
'ts-jest': {
|
||||
tsconfig: path.join(rootDir, 'tsconfig.json'),
|
||||
},
|
||||
}),
|
||||
testTimeout: 20000,
|
||||
verbose: false,
|
||||
silent: false,
|
||||
|
||||
@@ -9,42 +9,46 @@
|
||||
* and so on..
|
||||
*/
|
||||
|
||||
/* eslint-disable import/first */
|
||||
|
||||
// Set before imports, see https://github.com/facebook/jest/issues/12162
|
||||
process.env.FORCE_COLOR = '1';
|
||||
process.env.NODE_ENV = 'test';
|
||||
|
||||
import path from 'path';
|
||||
import { runCLI } from '@jest/core';
|
||||
import { cleanWorkspace } from './test-utils-vscode';
|
||||
|
||||
const rootDir = path.resolve(__dirname, '../..');
|
||||
const rootDir = path.join(__dirname, '../..');
|
||||
|
||||
export function run(): Promise<void> {
|
||||
const errWrite = process.stderr.write;
|
||||
|
||||
let remaining = '';
|
||||
process.stderr.write = (buffer: string) => {
|
||||
console.log(buffer);
|
||||
const lines = (remaining + buffer).split('\n');
|
||||
remaining = lines.pop() as string;
|
||||
// Trim long lines because some uninformative code dumps will flood the
|
||||
// console or, worse, be suppressed altogether because of their size.
|
||||
lines.forEach(l => console.log(l.substr(0, 300)));
|
||||
return true;
|
||||
};
|
||||
|
||||
// process.on('unhandledRejection', err => {
|
||||
// throw err;
|
||||
// });
|
||||
process.env.FORCE_COLOR = '1';
|
||||
process.env.NODE_ENV = 'test';
|
||||
process.env.BABEL_ENV = 'test';
|
||||
|
||||
return new Promise(async (resolve, reject) => {
|
||||
await cleanWorkspace();
|
||||
try {
|
||||
const { results } = await runCLI(
|
||||
{
|
||||
rootDir,
|
||||
roots: ['<rootDir>/src'],
|
||||
transform: JSON.stringify({ '^.+\\.ts$': 'ts-jest' }),
|
||||
runInBand: true,
|
||||
testRegex: '\\.(test|spec)\\.ts$',
|
||||
testEnvironment:
|
||||
'<rootDir>/src/test/support/extended-vscode-environment.js',
|
||||
testEnvironment: '<rootDir>/src/test/support/vscode-environment.js',
|
||||
setupFiles: ['<rootDir>/src/test/support/jest-setup.ts'],
|
||||
setupFilesAfterEnv: ['jest-extended'],
|
||||
globals: JSON.stringify({
|
||||
'ts-jest': {
|
||||
tsconfig: path.resolve(rootDir, './tsconfig.json'),
|
||||
},
|
||||
}),
|
||||
testTimeout: 30000,
|
||||
useStderr: true,
|
||||
verbose: true,
|
||||
@@ -71,6 +75,7 @@ export function run(): Promise<void> {
|
||||
return reject(error);
|
||||
} finally {
|
||||
process.stderr.write = errWrite.bind(process.stderr);
|
||||
await cleanWorkspace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
// Based on https://github.com/svsool/vscode-memo/blob/master/src/test/env/ExtendedVscodeEnvironment.js
|
||||
const VscodeEnvironment = require('jest-environment-vscode');
|
||||
const NodeEnvironment = require('jest-environment-node');
|
||||
const vscode = require('vscode');
|
||||
|
||||
const initialVscode = vscode;
|
||||
class ExtendedVscodeEnvironment extends VscodeEnvironment {
|
||||
class VscodeEnvironment extends NodeEnvironment {
|
||||
async setup() {
|
||||
await super.setup();
|
||||
this.global.vscode = vscode;
|
||||
|
||||
// Expose RegExp otherwise document.getWordRangeAtPosition won't work as supposed.
|
||||
// Implementation of getWordRangeAtPosition uses "instanceof RegExp" which returns false
|
||||
// due to Jest running tests in the different vm context.
|
||||
// See https://github.com/nodejs/node-v0.x-archive/issues/1277.
|
||||
// And also https://github.com/microsoft/vscode-test/issues/37#issuecomment-700167820
|
||||
this.global.RegExp = RegExp;
|
||||
this.global.vscode = vscode;
|
||||
|
||||
vscode.workspace
|
||||
.getConfiguration()
|
||||
.update('foam.edit.linkReferenceDefinitions', 'off');
|
||||
}
|
||||
|
||||
async teardown() {
|
||||
this.global.vscode = initialVscode;
|
||||
this.global.vscode = {};
|
||||
await super.teardown();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ExtendedVscodeEnvironment;
|
||||
module.exports = VscodeEnvironment;
|
||||
@@ -13,7 +13,7 @@ import { randomString, wait } from './test-utils';
|
||||
Logger.setLevel('error');
|
||||
|
||||
export const cleanWorkspace = async () => {
|
||||
const files = await vscode.workspace.findFiles('**', '.vscode');
|
||||
const files = await vscode.workspace.findFiles('**', '{.vscode,.keep}');
|
||||
await Promise.all(files.map(f => vscode.workspace.fs.delete(f)));
|
||||
};
|
||||
|
||||
|
||||
@@ -109,3 +109,6 @@ export const randomString = (len = 5) =>
|
||||
.fill('')
|
||||
.map(() => chars.charAt(Math.floor(Math.random() * chars.length)))
|
||||
.join('');
|
||||
|
||||
export const getRandomURI = () =>
|
||||
URI.file('/random-uri-root/' + randomString() + '.md');
|
||||
|
||||
11
packages/foam-vscode/syntaxes/injection.json
Normal file
11
packages/foam-vscode/syntaxes/injection.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"scopeName": "foam.wikilink.injection",
|
||||
"injectionSelector": "L:meta.paragraph.markdown",
|
||||
"patterns": [
|
||||
{
|
||||
"contentName": "string.other.link.title.markdown.foam",
|
||||
"begin": "\\[\\[",
|
||||
"end": "\\]\\]"
|
||||
}
|
||||
]
|
||||
}
|
||||
24
yarn.lock
24
yarn.lock
@@ -2250,11 +2250,6 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
|
||||
integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
|
||||
|
||||
"@types/github-slugger@^1.3.0":
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/github-slugger/-/github-slugger-1.3.0.tgz#16ab393b30d8ae2a111ac748a015ac05a1fc5524"
|
||||
integrity sha512-J/rMZa7RqiH/rT29TEVZO4nBoDP9XJOjnbbIofg7GQKs4JIduEO3WLpte+6WeUz/TcrXKlY+bM7FYrp8yFB+3g==
|
||||
|
||||
"@types/glob@^7.1.1":
|
||||
version "7.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183"
|
||||
@@ -2954,7 +2949,7 @@ babel-jest@^24.9.0:
|
||||
chalk "^2.4.2"
|
||||
slash "^2.0.0"
|
||||
|
||||
babel-jest@^26.2.2, babel-jest@^26.6.3:
|
||||
babel-jest@^26.6.3:
|
||||
version "26.6.3"
|
||||
resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-26.6.3.tgz#d87d25cb0037577a0c89f82e5755c5d293c01056"
|
||||
integrity sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==
|
||||
@@ -4283,11 +4278,6 @@ emittery@^0.7.1:
|
||||
resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.7.2.tgz#25595908e13af0f5674ab419396e2fb394cdfa82"
|
||||
integrity sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==
|
||||
|
||||
"emoji-regex@>=6.0.0 <=6.1.1":
|
||||
version "6.1.1"
|
||||
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.1.1.tgz#c6cd0ec1b0642e2a3c67a1137efc5e796da4f88e"
|
||||
integrity sha1-xs0OwbBkLio8Z6ETfvxeeW2k+I4=
|
||||
|
||||
emoji-regex@^7.0.1:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
|
||||
@@ -5312,13 +5302,6 @@ gitconfiglocal@^1.0.0:
|
||||
dependencies:
|
||||
ini "^1.3.2"
|
||||
|
||||
github-slugger@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.3.0.tgz#9bd0a95c5efdfc46005e82a906ef8e2a059124c9"
|
||||
integrity sha512-gwJScWVNhFYSRDvURk/8yhcFBee6aFjye2a7Lhb2bUyRulpIoek9p0I9Kt7PT67d/nUlZbFu8L9RLiA0woQN8Q==
|
||||
dependencies:
|
||||
emoji-regex ">=6.0.0 <=6.1.1"
|
||||
|
||||
glob-parent@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae"
|
||||
@@ -6515,11 +6498,6 @@ jest-environment-node@^26.6.2:
|
||||
jest-mock "^26.6.2"
|
||||
jest-util "^26.6.2"
|
||||
|
||||
jest-environment-vscode@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-environment-vscode/-/jest-environment-vscode-1.0.0.tgz#96367fe8531047e64359e0682deafc973bfaea91"
|
||||
integrity sha512-VKlj5j5pNurFEwWPaDiX1kBgmhWqcJTAZsvEX1x5lh0/+5myjk+qipEs/dPJVRbBPb3XFxiR48XzGn+wOU7SSQ==
|
||||
|
||||
jest-extended@^0.11.5:
|
||||
version "0.11.5"
|
||||
resolved "https://registry.yarnpkg.com/jest-extended/-/jest-extended-0.11.5.tgz#f063b3f1eaadad8d7c13a01f0dfe0f538d498ccf"
|
||||
|
||||
Reference in New Issue
Block a user