Compare commits

..

182 Commits

Author SHA1 Message Date
Riccardo Ferretti
cae3bffad1 update yarn.lock file 2021-11-09 00:38:21 +01:00
Riccardo Ferretti
ae10a89eab vscode-test 1.6.1 2021-11-09 00:38:21 +01:00
Riccardo Ferretti
635cc577fc updated vscode engine version and test instance version 2021-11-09 00:38:20 +01:00
Riccardo Ferretti
5f7b3b7c02 v0.15.4 2021-11-09 00:34:18 +01:00
Riccardo Ferretti
9ed0d6e18e prepare 0.15.4 2021-11-09 00:33:45 +01:00
Riccardo Ferretti
0140748550 improved URI.toFsPath 2021-11-09 00:24:53 +01:00
Riccardo
356dcc5579 Consolidate use of Foam URI (#820)
* always convert vscode.Uri to foam.URI

* Improve handling on Windows paths in URI

- convert to upper case drive letter
- normalize use of Windows conversion in URI
- added more test cases

* Fixed tests
2021-11-08 23:39:01 +01:00
Riccardo Ferretti
265afdee19 v0.15.3 2021-11-08 11:34:18 +01:00
Riccardo Ferretti
de7c686f75 Prepare 0.15.3 2021-11-08 11:34:05 +01:00
Riccardo
8dfc5bd2ff Throw exception instead of process.exit (#819) 2021-11-08 11:12:15 +01:00
Riccardo
b3c5e75aa2 Fixing some test issues (#818)
* renamed test scripts

* improved hover provider tests

* removed buffering of log lines in test suite
2021-11-06 17:48:27 +01:00
Paul de Raaij
000da4bd1c Allow inclusion of note when using reference definitions (#808)
* Allow inclusion of note when using reference definitions

* Add additional comments
2021-11-04 20:17:03 +01:00
allcontributors[bot]
86749940c2 docs: add AndreiD049 as a contributor for code (#815)
* 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-11-04 13:09:09 +01:00
AndreiD049
27f9a08870 replaced vscode uri with foam uri when generating references (#814) 2021-11-04 11:58:15 +01:00
Riccardo Ferretti
e791726692 fixed logging in test suite 2021-11-03 10:54:15 +01:00
Riccardo Ferretti
a3c00744ca fixed linting errors 2021-11-03 10:52:27 +01:00
allcontributors[bot]
00220b1f6c docs: add memeplex as a contributor for code (#812)
* 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-11-03 10:31:56 +01:00
memeplex
759f4f1963 Avoid delaying decorations on editor switch (#811) 2021-11-03 10:31:20 +01:00
Riccardo Ferretti
d86fc7f433 removed outdated use of links 2021-11-01 20:04:37 +01:00
Riccardo
bd9c6806fa tweaks to test suite (#804) 2021-10-28 23:13:20 +02:00
Riccardo Ferretti
4c9a9cec56 v0.15.2 2021-10-27 12:11:02 +02:00
Riccardo Ferretti
8a91a6ab36 Prepare v0.15.2 2021-10-27 12:05:39 +02:00
Paul de Raaij
667037bc14 Improve generation of link reference definitions (#786)
* Fixes the removal of explicitly defined link references

* Add use case of explicit & implicit
2021-10-27 10:58:10 +02:00
allcontributors[bot]
30cc9fc9f0 docs: add eltociear as a contributor for doc (#801)
* 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-10-27 10:52:41 +02:00
Ikko Ashimine
abed7be3ec Fix typo in write-your-notes-in-github-gist.md (#798)
recieve -> receive
2021-10-27 10:51:27 +02:00
Riccardo
d31e094358 Added support for target date variables in daily note template (#781)
* added support for target date variables in daily note template

* added FOAM_DATE_* variables to resolver

* Document `FOAM_DATE_*` template variables

* Add CHANGELOG entry

Co-authored-by: Michael Overmeyer <michael.overmeyer@shopify.com>
2021-10-27 10:50:58 +02:00
Riccardo
f320af05c5 Improve graph performance by batching painting (#795) 2021-10-26 13:01:19 +02:00
Paul de Raaij
ee229dac84 Apply entire tag regex to the preview window (#785) 2021-10-25 19:56:51 +02:00
allcontributors[bot]
877d843f60 docs: add Laptop765 as a contributor for doc (#796)
* 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-10-25 19:51:22 +02:00
Paul
af65e4d5f7 Add some basic details about multi-root workspaces (#775)
* Include details about multi-root workspaces

* Reword and clarify
2021-10-25 19:50:47 +02:00
Riccardo Ferretti
dd9fa0af79 Link decorations now enabled by default 2021-10-25 19:22:32 +02:00
Riccardo Ferretti
14f68aea30 minor fixes around VS Code test configurations and suite reporting 2021-10-25 19:22:00 +02:00
Riccardo Ferretti
f68c2ab6db Color graph filter control based on style of node type 2021-10-22 12:33:19 +02:00
Riccardo Ferretti
bae99a6184 fixed dependencies and types 2021-10-21 10:09:45 +02:00
Riccardo Ferretti
861f7dbba7 v0.15.1 2021-10-21 09:01:19 +02:00
Riccardo Ferretti
6a4b90d6d7 Prepare 0.15.1 2021-10-21 08:59:34 +02:00
Riccardo
f73ddb88d4 Fixed test suite
* tweaking error propagation

* updated xvfb-action version

* improved logging

* only adding actually failing tests to failures (no comment)
2021-10-19 12:42:41 +02:00
Riccardo Ferretti
41ca70f23c better handling of output streams in tests and small change around computing which tests to run 2021-10-19 10:53:19 +02:00
Riccardo
7cf7811b85 Include other connected notes into link hovers (#780)
* Include other connected notes into link hovers

* reorganized hover provider tests and added some
2021-10-11 11:59:15 +02:00
Riccardo
eef0aa7f0b Improved filtering controls on graph visualization (#782)
* improved handling of filters in graph view
* code clean up
2021-10-11 11:55:54 +02:00
Riccardo
d222cfbbec Consolidate foam-core within foam-vscode (#774)
* moved `foam-core` inside `foam-vscode`

* updated contribution guide to reflect new modules setup

* improved testing

* consolidate to root yarn.lock files

* tweaking CI workflow && using github secrets to force cache refresh

* improved linting configuration. `core` module cannot depend on other parts of the `foam-vscode` package
2021-10-09 11:09:02 +02:00
Riccardo Ferretti
ee7a891976 v0.15.0 2021-10-04 10:05:46 +02:00
Riccardo Ferretti
680e317dbf Preparation for 0.15.0 2021-10-04 10:05:15 +02:00
Riccardo Ferretti
dbb46369a2 Added Project Manager to recommended extensions list (reported by @readingsnail) 2021-09-14 18:49:04 +02:00
Riccardo Ferretti
562da95f90 Bump fast-array-diff from 1.0.0 to 1.0.1 2021-09-14 18:37:32 +02:00
Riccardo Ferretti
fc03e07eeb removed extra file 2021-09-14 18:24:09 +02:00
Riccardo Ferretti
ccea5666bf fixed CI workflow (caching) 2021-09-14 18:23:39 +02:00
dannysemi
2a7a909ac5 Issue #530: Introduced DAT in dataviz view, and sending properties to it (#737)
* Introduced DAT.ui

* Sending properties and tags to graph for better data handling
2021-09-13 17:33:49 +02:00
Paul de Raaij
efac46174a Proposal and basic feature to include notes into a note (#741)
* Add the functionality to include notes in a note

* Add proposal of embedding

* Add tests for including notes

* Add documentation for inclusion feature
2021-09-13 17:23:40 +02:00
Riccardo Ferretti
4c5d996586 minor change in hash computation for CI 2021-09-13 17:17:28 +02:00
Jonas SPRENGER
6de0024b0b bugfix/705: replacing Indexable Types with Map (#729)
* bugfix/705: replacing Indexable Types with Map

* test for resources/placeholders named like JS proto properties

Co-authored-by: Jonas <jojo@srg.com>
2021-09-13 17:10:46 +02:00
allcontributors[bot]
70b0fae078 docs: add JonasSprenger as a contributor for code (#763)
* 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-09-06 23:31:54 +02:00
Jonas SPRENGER
fd9bf8f04f Implement hover feature for wikilinks (#728)
* Implement hover feature for wikilinks

* Make hover configuration reactive
2021-09-06 23:31:04 +02:00
allcontributors[bot]
630a77782d docs: add ksprashu as a contributor for doc (#756)
* 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-09-01 21:19:08 +02:00
Prashanth Subrahmanyam
6fdce389e9 Update recommended extensions based on template (#755) 2021-09-01 21:18:08 +02:00
allcontributors[bot]
9ce5a9528f docs: add theowenyoung as a contributor for doc, content (#753)
* 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-08-31 19:51:03 +02:00
Owen Young
ca821d3928 Add another gatsby template (#752)
Add foam-template-gatsby-theme-primer-wiki
2021-08-31 19:49:05 +02:00
allcontributors[bot]
9dacadedfc docs: add Pearcekieser as a contributor for doc (#750)
* 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-08-27 13:06:34 +02:00
Pearcekieser
0c07e7535e Add Recommended Extension: TODO Tree (#748)
issue: #740
2021-08-27 13:05:55 +02:00
Riccardo Ferretti
dddc379f2b fix 734: improved logging in markdown-provider 2021-07-28 11:51:38 +02:00
Riccardo
e83740d65a Tags improvements (#733)
* No longer parsing tags inside codeblocks

* fixed linting

* Using Tag data structure in Resource
2021-07-28 11:45:19 +02:00
Riccardo Ferretti
eddd9de665 foam-vscode to use latest foam-core 2021-07-25 15:57:31 +02:00
Riccardo Ferretti
7f6004dd6d v0.14.2 2021-07-24 10:20:31 +02:00
Riccardo Ferretti
1258cef04c Preparation for 0.14.2 2021-07-24 10:19:16 +02:00
Paul de Raaij
7adbffcfc2 Introduce autocompletion for tags (#708) 2021-07-24 00:10:42 +02:00
Michael Overmeyer
8395a408f2 Make navigating to a placeholder wikilink use the default template (#712) 2021-07-23 16:50:32 +02:00
Michael Overmeyer
721a6cc935 Standardize on wikilink, MediaWiki, and GitHub (#716)
* Standardize on `wikilink`

Not `wiki-link`, nor `wiki link`

https://en.wikipedia.org/wiki/Help:Link#Wikilinks

* Standardize on `MediaWiki`

Not `media-wiki`, nor `mediawiki`

https://www.mediawiki.org/wiki/MediaWiki

* Standardize on `GitHub`

Not `Github`

Co-authored-by: Riccardo <code@riccardoferretti.com>
2021-07-22 00:19:35 +02:00
Paul de Raaij
1659fe37d9 Respect the ignore globs when searching all files (#730) 2021-07-21 11:22:23 +02:00
Riccardo Ferretti
32f9120864 updated link to log output in bug template 2021-07-18 16:37:32 +02:00
Michael Overmeyer
cec0aecd06 Remove Markdown Notes from recommended extensions (#722) 2021-07-17 21:03:45 +02:00
Riccardo Ferretti
c59584d342 v0.14.1 2021-07-15 01:24:25 +02:00
Riccardo Ferretti
ea930d3d17 preparation for 0.14.1 2021-07-15 01:21:11 +02:00
Paul de Raaij
130b839ee9 Add a null check to prevent preview to break (#718) 2021-07-15 01:11:07 +02:00
Riccardo Ferretti
1b4dc8a8b1 v0.14.0 2021-07-13 13:50:25 +02:00
Riccardo Ferretti
7fcbf1acf1 Preparation for 0.14.0 2021-07-13 13:48:44 +02:00
Michael Overmeyer
011706904b Make daily notes use templates (#700) 2021-07-13 12:24:48 +02:00
Michael Overmeyer
c14e1e6349 Migrate create-from-template to use Foam's URI instead of VSCode's Uri (#709) 2021-07-12 23:24:21 +02:00
Paul de Raaij
97629a2ce6 Removes escape character of an alias when setting target (#697)
* Removes escape character of an alias when setting WikiLink target

* Alter tearDown of document-link-provider test

* Disable link reference defintion generation for all tests
2021-07-12 22:41:33 +02:00
Paul de Raaij
6b3eef43a8 Allows wikilinks to be opened in the editor again (#710) 2021-07-12 20:49:25 +02:00
Paul de Raaij
d4adce6730 Adds FAQ about enabling and disabling Foam (#706)
* Adss FAQ about enabling and disabling Foam

* Update frequently-asked-questions.md
2021-07-12 19:16:57 +02:00
allcontributors[bot]
ae65f53540 docs: add rafo as a contributor for doc (#703)
* 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-07-06 12:57:30 +02:00
Rafael Riedel
8998204298 Update recommended-extensions.md (#702)
Changed "Mermaid Support for Preview" to the extensions new name: "Markdown Preview Mermaid Support"
2021-07-06 12:56:46 +02:00
Michael Overmeyer
92f6e001e5 Fix implicit insertion of FOAM_SELECTED_TEXT (#701)
* Only do the insertion when necessary.
* Insert using the correct whitespace.
2021-07-06 00:37:39 +02:00
Paul de Raaij
889f93a7e1 Move selected text into a new note and auto create a backlink (#666)
template and functionality to use selected text in a new note
2021-07-04 20:44:22 +02:00
Paul de Raaij
4db8c55969 Only remove link definition token that contain an alias divider (#698)
* be more conservative in removing link definitions

* Update packages/foam-vscode/src/features/preview-navigation.ts

Co-authored-by: Riccardo <code@riccardoferretti.com>

Co-authored-by: Riccardo <code@riccardoferretti.com>
2021-07-04 20:38:52 +02:00
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
Riccardo Ferretti
2e435a3828 v0.13.7 2021-06-05 15:53:16 +02:00
Riccardo Ferretti
a0f83e7510 refactored code to avoid circular dependency 2021-06-05 15:50:04 +02:00
Riccardo Ferretti
641024b01b added dependency on replace-ext (fix for #667 we hope..) 2021-06-05 15:49:34 +02:00
Riccardo Ferretti
c5a7d02656 include ES2019 library in tsconfig for vscode package 2021-06-05 15:30:35 +02:00
Riccardo Ferretti
b76196cd23 removed Foam local plugin experimental feature 2021-06-05 15:17:23 +02:00
Riccardo Ferretti
61ae468a70 v0.13.6 2021-06-05 14:58:22 +02:00
Riccardo Ferretti
6119278915 Removed support for Foam local plugins 2021-06-05 14:51:16 +02:00
Riccardo Ferretti
34c179123e v0.13.5 2021-06-05 00:30:24 +02:00
Riccardo Ferretti
c34394a0ea prepare for 0.13.5 2021-06-05 00:28:38 +02:00
Riccardo Ferretti
26c38a06ff fixes #665 - always access files in .foam/templates directory when looking for templates 2021-06-04 15:29:33 +02:00
Michael Overmeyer
d4623a2d91 Allow for YAML metadata in templates (#655)
* Add a frontmatter metadata parser

* Use the template metadata to determine the filepath to use

* Document template metadata

* Add name and description template metadata attributes

These are displayed in the template picker

* Document name and description template metadata attributes
2021-06-04 15:27:46 +02:00
dependabot[bot]
2f9507dc87 Bump ws from 7.3.1 to 7.4.6 in /packages/foam-vscode (#662)
Bumps [ws](https://github.com/websockets/ws) from 7.3.1 to 7.4.6.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/7.3.1...7.4.6)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-31 20:59:09 +02:00
Paul de Raaij
4db09070a8 Filter out tag references that are part of a nested tag (#661)
* Filter out tagreferences that are part fo a nested tag

* add test case for notes with parent and child tag
2021-05-31 20:57:40 +02:00
Riccardo Ferretti
5f99d9d5c6 v0.13.4 2021-05-26 13:39:18 +02:00
Riccardo Ferretti
9c1480197c Preparation for 0.13.4 2021-05-26 13:16:49 +02:00
Riccardo Ferretti
f1a6426046 updated documentation to reflect nested tags 2021-05-26 09:18:30 +02:00
Riccardo Ferretti
6de8baa6b5 updated yarn.lock 2021-05-26 09:18:01 +02:00
Riccardo Ferretti
27ff023a26 fix loading of markdownIt extensions 2021-05-26 09:12:14 +02:00
Paul de Raaij
690eb10856 Add support for nested tags (#643)
* Add support for nested tags

* Adds test for feature
2021-05-26 09:11:39 +02:00
Michael Overmeyer
1cb8174a9f Always ask for the note title when creating from template (#645)
* Fix snake_case to camelCase

* Always ask for the note title when creating from the default template

In the future, we'll make this conditional on whether the template provides the filepath to use in its metadata block
2021-05-22 21:46:47 +02:00
allcontributors[bot]
2141bac24a docs: add pderaaij as a contributor (#650)
* 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-05-22 21:39:50 +02:00
Paul de Raaij
6abef8f8e7 Allow for optionality in title prop in frontmatter (#647) 2021-05-22 21:39:03 +02:00
dependabot[bot]
c797a00223 Bump nokogiri from 1.11.1 to 1.11.5 in /docs (#646)
Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.11.1 to 1.11.5.
- [Release notes](https://github.com/sparklemotion/nokogiri/releases)
- [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.11.1...v1.11.5)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-20 15:35:51 +02:00
José Duarte
7c01fb13f0 Upgrade force-graph to 1.40.5 (#642) 2021-05-20 11:14:15 +02:00
dependabot[bot]
abbc2bbb14 Bump lodash from 4.17.19 to 4.17.21 in /packages/foam-core (#628)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.19 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.19...4.17.21)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-14 11:28:11 +02:00
dependabot[bot]
bb7fee24bb Bump hosted-git-info from 2.8.8 to 2.8.9 in /packages/foam-core (#629)
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)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-14 11:27:22 +02:00
dependabot[bot]
43ef3a3e2b Bump lodash from 4.17.20 to 4.17.21 in /packages/foam-vscode (#630)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.20 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.20...4.17.21)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-14 11:26:59 +02:00
dependabot[bot]
da69a3057f Bump hosted-git-info from 2.8.8 to 2.8.9 in /packages/foam-vscode (#631)
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)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-14 11:26:29 +02:00
Riccardo
2d06f26bbf fix #638 link to license page 2021-05-13 15:55:54 +02:00
Riccardo
edbe128e1e fix #546 - title yaml property can also be a number 2021-05-13 13:09:09 +02:00
Riccardo Ferretti
af0c2bbaa3 v0.13.3 2021-05-11 21:40:56 +02:00
Riccardo Ferretti
700bfc1b26 addressing windows issue with provider matching (related to #617) 2021-05-11 21:25:25 +02:00
Riccardo Ferretti
a6d5c04453 improve bootstrap performance
we wait to create the graph, as changes to the workspace will cause it to be recomputed.
so, first load all resources from the initial providers, then compute the graph.
2021-05-11 21:22:19 +02:00
Riccardo Ferretti
b0c42cead2 setting logging level to error for all tests 2021-05-11 21:12:38 +02:00
Riccardo Ferretti
6c643adb9d Prepare for 0.13.3 2021-05-09 23:13:27 +02:00
Riccardo Ferretti
ca7fdefaae improvemets in matcher and linting 2021-05-09 23:13:27 +02:00
Riccardo Ferretti
149d5f5a7c fix #617 - fixed error in file matching in MarkdownProvider 2021-05-09 22:50:42 +02:00
Michael Overmeyer
be80857fd1 Handle users cancelling "Create New Note" commands (#623) 2021-05-09 22:50:18 +02:00
Michael Overmeyer
611fa7359d Completely ignore unknown Foam variables (#622)
If we don't know it we shouldn't touch it
Previously it replaced the variable with the variables name
2021-05-09 18:23:06 +02:00
Riccardo Ferretti
08b7e7a231 fixed isMarkdown function to check the .md extension (related to #617) 2021-05-07 23:53:14 +02:00
Riccardo Ferretti
0a259168c7 fix #618: properly printing file name 2021-05-07 22:58:44 +02:00
Riccardo Ferretti
f3d0569c76 fixed Barabazs contributor name 2021-05-06 12:26:22 +02:00
Riccardo Ferretti
502129d5ac v0.13.2 2021-05-06 10:10:51 +02:00
Riccardo Ferretti
d29bf16db1 prepare 0.13.2 2021-05-06 10:10:22 +02:00
Riccardo Ferretti
d228c7cb18 fixed test 2021-05-06 10:04:00 +02:00
Riccardo Ferretti
78078cf338 improved foam settings 2021-05-06 10:04:00 +02:00
Riccardo Ferretti
fe65883bc5 fix #600 - clicking on notes in placeholder and orphan panels now navigates to them 2021-05-06 10:04:00 +02:00
allcontributors[bot]
20b5261c5c docs: add EngincanV as a contributor (#615)
* 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-05-06 10:02:12 +02:00
Engincan VESKE
f91cfe5d0d Update capture-notes-with-shortcuts-and-github-actions.md (#613) 2021-05-06 10:01:42 +02:00
Michael Overmeyer
1ab9cc5f4a Add streamline "Create new note" command (#601)
* Add new `Create New Note` command
It is the streamlined counterpart to `Create New Note From Template`

* Simplify the variable Regex
\W is equivalent to [^A-Za-z0-9_]
2021-05-03 13:48:14 +02:00
allcontributors[bot]
02ff681700 docs: add Barabazs as a contributor (#610)
* 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-05-03 13:20:26 +02:00
Barabas
2d9c3be0e6 Add support for stylable tags (#598) 2021-05-03 13:19:37 +02:00
Robin King
78cf602347 fix: (#592) extra autocomplete hints outside wiki-link brackets (#596) 2021-05-03 13:02:28 +02:00
dependabot[bot]
898c7b4387 Bump rexml from 3.2.4 to 3.2.5 in /docs (#607)
Bumps [rexml](https://github.com/ruby/rexml) from 3.2.4 to 3.2.5.
- [Release notes](https://github.com/ruby/rexml/releases)
- [Changelog](https://github.com/ruby/rexml/blob/master/NEWS.md)
- [Commits](https://github.com/ruby/rexml/compare/v3.2.4...v3.2.5)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-03 11:40:40 +02:00
Riccardo
7412d518d7 Spike on FoamWorkspace and DataStore refactor (#593)
* extracted graph from workspace

* refactored datastore

* dataviz to use URI for placeholder detection

* graph uses uris, not resources

* adding placeholder in graph

* link completion to use graph

* API v1 - Resource refactoring (#595)

* aside: tweaked jest extension configuration

* added provider for markdown

* removed file check in URI

the problem is that it makes the URI dependent on the disk, which makes testing harder.
The change was originally introduced to prevent Foam from treating directories ending in .md as markdown files, but the check needs to probably happen somewhere else, e.g. in `FileDataStore.list` - or directories should be expressed with a trailing slash (to check whether that breaks the URI convention)

* Various changes

- `resolveLink` now delegates to providers
- added `read` method in providers and `FoamWorkspace`
- improved `Matcher` API
- updated tests to use workspace with providers
- delegating more to workspace now it can read files (simplifies wiring and exposed API surface)
- provider init returns a promise, so it can be awaited on
- `IDataStore` now has `list` method, to encapsulate all access to FS

* improved windows support in URI and matcher

* improved grouped resources interface

* added readAsMarkdown in provider, useful for tooltip generation with preview in vscode
2021-04-30 16:50:16 +02:00
allcontributors[bot]
e6030ac562 docs: add daniel-vera-g as a contributor (#603)
* 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-04-25 23:58:47 +02:00
Daniel VG
d6d958bc92 Docs: Fix markdown formatting issues (#599)
* Fix: Right links and formatting

* Docs: Run markdownlint to automatically fix minor formatting errors

* Style: Format with markdownlint and not prettier
2021-04-25 23:58:02 +02:00
Riccardo Ferretti
fd7a24c5fc v0.13.1 2021-04-21 21:10:48 +02:00
Riccardo Ferretti
41b3c6fbfb Prepare 0.13.1 2021-04-21 21:10:15 +02:00
Robin King
84b2ab6e42 fix:(#591) 'foam-vscode.open-daily-note' error on Windows (#594)
* when calling URI.file more than two time on windows
* a extra slash('/') at path's beginning may cause some problems
* so add a condition to solve it
2021-04-21 21:04:04 +02:00
dependabot[bot]
6cf184ba23 Bump ssri from 6.0.1 to 6.0.2 (#590)
Bumps [ssri](https://github.com/npm/ssri) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/npm/ssri/releases)
- [Changelog](https://github.com/npm/ssri/blob/v6.0.2/CHANGELOG.md)
- [Commits](https://github.com/npm/ssri/compare/v6.0.1...v6.0.2)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-04-19 12:15:02 +02:00
Riccardo Ferretti
6ad8211f56 v0.13.0 2021-04-19 11:45:18 +02:00
Riccardo Ferretti
ac247867d9 prepare for 0.13.0 2021-04-19 11:44:54 +02:00
allcontributors[bot]
46f0bf2830 docs: add dheepakg as a contributor (#588)
* 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-04-19 09:55:52 +02:00
Dheepak
f0d712d1ce Fixed LICENSE page issue occuring at github-pages. (#581) 2021-04-19 09:54:48 +02:00
Michael Overmeyer
b72bca661b Template variable refactor (#586)
* Switch the default note name to follow Obsidian filename style

Previously it was the style used by Markdown Links
Ref: https://github.com/foambubble/foam/pull/569#discussion_r611936272

* Refactor variable resolution

Taking the only good bits of [`FOAM_TITLE_SLUG`](https://github.com/foambubble/foam/pull/569).

* Use FOAM_TITLE as the default filename
2021-04-19 09:52:22 +02:00
Riccardo
ac5cd832f6 Added configuration to enable/disable link navigation (#584) 2021-04-16 12:29:19 +02:00
Riccardo
71e8f00e80 fixed #542 (#583) 2021-04-14 22:25:13 +02:00
Riccardo
b371f0fa7d Handle file errors more gracefully in FileDataStore (#578)
* handle file errors more gracefully in FileDataStore
2021-04-14 19:16:48 +02:00
Riccardo
b11a206b4a API v1 - Position and Range (#577)
* refactored position and range functions
2021-04-12 21:56:14 +02:00
Riccardo
c678375712 Wikilink completion (#554)
* placeholders are updated when creating connection, not when resolving link

* feature: link completion

* added tests

Co-authored-by: Jani Eväkallio <jani.evakallio@gmail.com>
2021-04-12 19:37:25 +02:00
Michael Overmeyer
b1bdf766b1 [Templates v2] Add FOAM_TITLE snippet variable (#549)
* Remove unused variables to appease the linter

* Remove unecessary escape character

To appease the linter

* Add FOAM_TITLE snippet variable
2021-04-10 22:02:46 +02:00
Riccardo
531bdab250 Refactored URI for Foam API v1 (#537)
* refactored URI to be less dependent on VS Code implementation
* moved uri tests in own file, and added test case from #507
* added license info for VS Code inspired code
* moved URI utility methods in abstract class for namespacing
* better names for some methods

Co-authored-by: Jonathan <jonny@mondago.com>
2021-04-05 14:22:51 +02:00
allcontributors[bot]
5fa04c7384 docs: add RobinKing as a contributor (#571)
* 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-04-05 13:52:29 +02:00
Robin King
1f95d0559c fixed bug with Chinese characters in tags (Issue #567) (#568)
Makes tags support Unicode Letters.
Makes it possible to create tags with Chinese characters -> Issue #567.
2021-04-05 13:51:46 +02:00
Riccardo Ferretti
f00886acac v0.12.1 2021-04-05 13:40:45 +02:00
Riccardo Ferretti
4895a8b84c prepare for 0.12.1 2021-04-05 13:39:57 +02:00
Riccardo
ea0f88475c introduced configuraiton option to make decorations optional (#558)
fixes #553 #547
2021-04-05 12:50:13 +02:00
Michael Overmeyer
567c87c285 Add a proposal for how templates should work (Templates v2) (#534) 2021-04-02 22:30:28 +02:00
Louie Christie
4ea076b949 docs: update instructions for Github pages (#559)
Because foam template defaults have been changed: ec2d44ad86 (diff-a5de3e5871ffcc383a2294845bd3df25d3eeff6c29ad46e3a396577c413bf357L16)
2021-04-02 09:04:33 +02:00
dependabot[bot]
bf80a40ad3 Bump y18n from 4.0.0 to 4.0.1 in /packages/foam-core (#555)
Bumps [y18n](https://github.com/yargs/y18n) from 4.0.0 to 4.0.1.
- [Release notes](https://github.com/yargs/y18n/releases)
- [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yargs/y18n/commits)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-04-01 18:22:17 +02:00
dependabot[bot]
85e687956f Bump y18n from 4.0.0 to 4.0.1 in /packages/foam-vscode (#556)
Bumps [y18n](https://github.com/yargs/y18n) from 4.0.0 to 4.0.1.
- [Release notes](https://github.com/yargs/y18n/releases)
- [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yargs/y18n/commits)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-04-01 18:21:59 +02:00
Michael Overmeyer
5f963fe895 Add a placeholder for the template file quick pick menu (#550)
Slightly nicer UX
2021-03-28 22:44:42 +02:00
223 changed files with 8783 additions and 16241 deletions

View File

@@ -643,6 +643,151 @@
"contributions": [
"doc"
]
},
{
"login": "RobinKing",
"name": "Robin King",
"avatar_url": "https://avatars.githubusercontent.com/u/1583193?v=4",
"profile": "http://robincn.com",
"contributions": [
"code"
]
},
{
"login": "dheepakg",
"name": "Dheepak ",
"avatar_url": "https://avatars.githubusercontent.com/u/4730170?v=4",
"profile": "http://twitter.com/deegovee",
"contributions": [
"doc"
]
},
{
"login": "daniel-vera-g",
"name": "Daniel VG",
"avatar_url": "https://avatars.githubusercontent.com/u/28257108?v=4",
"profile": "https://github.com/daniel-vera-g",
"contributions": [
"doc"
]
},
{
"login": "Barabazs",
"name": "Barabas",
"avatar_url": "https://avatars.githubusercontent.com/u/31799121?v=4",
"profile": "https://github.com/Barabazs",
"contributions": [
"code"
]
},
{
"login": "EngincanV",
"name": "Engincan VESKE",
"avatar_url": "https://avatars.githubusercontent.com/u/43685404?v=4",
"profile": "http://enginveske@gmail.com",
"contributions": [
"doc"
]
},
{
"login": "pderaaij",
"name": "Paul de Raaij",
"avatar_url": "https://avatars.githubusercontent.com/u/495374?v=4",
"profile": "http://www.paulderaaij.nl",
"contributions": [
"code"
]
},
{
"login": "bronson",
"name": "Scott Bronson",
"avatar_url": "https://avatars.githubusercontent.com/u/1776?v=4",
"profile": "https://github.com/bronson",
"contributions": [
"doc"
]
},
{
"login": "rafo",
"name": "Rafael Riedel",
"avatar_url": "https://avatars.githubusercontent.com/u/41793?v=4",
"profile": "http://rafaelriedel.de",
"contributions": [
"doc"
]
},
{
"login": "Pearcekieser",
"name": "Pearcekieser",
"avatar_url": "https://avatars.githubusercontent.com/u/5055971?v=4",
"profile": "https://github.com/Pearcekieser",
"contributions": [
"doc"
]
},
{
"login": "theowenyoung",
"name": "Owen Young",
"avatar_url": "https://avatars.githubusercontent.com/u/62473795?v=4",
"profile": "https://github.com/theowenyoung",
"contributions": [
"doc",
"content"
]
},
{
"login": "ksprashu",
"name": "Prashanth Subrahmanyam",
"avatar_url": "https://avatars.githubusercontent.com/u/476729?v=4",
"profile": "http://www.prashu.com",
"contributions": [
"doc"
]
},
{
"login": "JonasSprenger",
"name": "Jonas SPRENGER",
"avatar_url": "https://avatars.githubusercontent.com/u/25108895?v=4",
"profile": "https://github.com/JonasSprenger",
"contributions": [
"code"
]
},
{
"login": "Laptop765",
"name": "Paul",
"avatar_url": "https://avatars.githubusercontent.com/u/1468359?v=4",
"profile": "https://github.com/Laptop765",
"contributions": [
"doc"
]
},
{
"login": "eltociear",
"name": "Ikko Ashimine",
"avatar_url": "https://avatars.githubusercontent.com/u/22633385?v=4",
"profile": "https://bandism.net/",
"contributions": [
"doc"
]
},
{
"login": "memeplex",
"name": "memeplex",
"avatar_url": "https://avatars.githubusercontent.com/u/2845433?v=4",
"profile": "https://github.com/memeplex",
"contributions": [
"code"
]
},
{
"login": "AndreiD049",
"name": "AndreiD049",
"avatar_url": "https://avatars.githubusercontent.com/u/52671223?v=4",
"profile": "https://github.com/AndreiD049",
"contributions": [
"code"
]
}
],
"contributorsPerLine": 7,

View File

@@ -1,20 +1,18 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module"
},
"plugins": [
"@typescript-eslint"
],
"rules": {
"@typescript-eslint/class-name-casing": "warn",
"@typescript-eslint/semi": "warn",
"curly": "warn",
"eqeqeq": "warn",
"no-throw-literal": "warn",
"semi": "off",
"require-await": "warn"
}
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module"
},
"plugins": ["@typescript-eslint", "import"],
"rules": {
"@typescript-eslint/class-name-casing": "warn",
"@typescript-eslint/semi": "warn",
"curly": "warn",
"eqeqeq": "warn",
"no-throw-literal": "warn",
"semi": "off",
"require-await": "warn"
}
}

View File

@@ -20,4 +20,4 @@ labels: bug
Feel free to attach any of the following that might help with debugging the issue:
- screenshots
- a zip with a minimal repo to reproduce the issue
- the Foam log in VsCode (see [instructions](https://github.com/foambubble/foam/blob/master/docs/foam-logging-in-vscode.md))
- the Foam log in VsCode (see [instructions](https://github.com/foambubble/foam/blob/master/docs/features/foam-logging-in-vscode.md))

View File

@@ -3,17 +3,15 @@ name: CI
on:
push:
branches:
- '**'
# The following will also make the workflow run on all PRs, internal and external.
# This would create duplicate runs, that we are skipping by adding the "if" to the jobs below.
# See https://github.community/t/duplicate-checks-on-push-and-pull-request-simultaneous-event/18012
- master
pull_request:
branches:
- master
jobs:
lint:
name: Lint
runs-on: ubuntu-18.04
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != 'foambubble/foam'
steps:
- uses: actions/checkout@v1
- name: Setup Node
@@ -27,7 +25,7 @@ jobs:
node_modules
*/*/node_modules
packages/foam-vscode/.vscode-test
key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}-${{ hashFiles('packages/foam-vscode/src/test/run-tests.ts') }}
key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock', 'packages/foam-vscode/src/test/run-tests.ts') }}-${{ secrets.CACHE_VERSION }}
- name: Install Dependencies
run: yarn
- name: Check Lint Rules
@@ -39,7 +37,6 @@ jobs:
matrix:
os: [macos-10.15, ubuntu-18.04, windows-2019]
runs-on: ${{ matrix.os }}
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != 'foambubble/foam'
env:
OS: ${{ matrix.os }}
steps:
@@ -55,12 +52,12 @@ jobs:
node_modules
*/*/node_modules
packages/foam-vscode/.vscode-test
key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}-${{ hashFiles('packages/foam-vscode/src/test/run-tests.ts') }}
key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock', 'packages/foam-vscode/src/test/run-tests.ts') }}-${{ secrets.CACHE_VERSION }}
- name: Install Dependencies
run: yarn
- name: Build Packages
run: yarn build
- name: Run Tests
uses: GabrielBB/xvfb-action@v1.0
uses: GabrielBB/xvfb-action@v1.4
with:
run: yarn test

100
.vscode/launch.json vendored
View File

@@ -3,83 +3,29 @@
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
{
"version": "0.2.0",
"inputs": [
"version": "0.2.0",
"configurations": [
{
"id": "packageName",
"type": "pickString",
"description": "Select the package in which this test is located",
"options": ["foam-core", "foam-vscode"],
"default": "foam-core"
"type": "node",
"name": "Debug Jest Tests",
"request": "launch",
"runtimeArgs": ["workspace", "foam-vscode", "run", "test"], // ${yarnWorkspaceName} is what we're missing
"args": ["--runInBand"],
"runtimeExecutable": "yarn",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"disableOptimisticBPs": true
},
{
"name": "Run VSCode Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}/packages/foam-vscode"
],
"outFiles": ["${workspaceFolder}/packages/foam-vscode/out/**/*.js"],
"preLaunchTask": "${defaultBuildTask}"
}
],
"configurations": [
{
"type": "node",
"name": "vscode-jest-tests",
"request": "launch",
"runtimeArgs": ["workspace", "${input:packageName}", "run", "test"], // ${yarnWorkspaceName} is what we're missing
"args": [
"--runInBand"
],
"runtimeExecutable": "yarn",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"disableOptimisticBPs": true,
},
{
"name": "Debug Jest Tests",
"type": "node",
"request": "launch",
"runtimeArgs": [
"--inspect-brk",
"${workspaceRoot}/node_modules/.bin/tsdx",
"test",
],
"console": "integratedTerminal",
"cwd": "${workspaceFolder}/packages/foam-core",
"internalConsoleOptions": "neverOpen"
},
{
"name": "Run VSCode Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}/packages/foam-vscode"
],
"outFiles": [
"${workspaceFolder}/packages/foam-vscode/out/**/*.js"
],
"preLaunchTask": "${defaultBuildTask}"
},
// @NOTE: This task is broken. VSCode e2e tests are currently disabled
// due to incompability of jest and mocha inside a typescript monorepo
// Contributions to fix this are welcome!
{
"name": "Test VSCode Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}/packages/foam-vscode",
"--extensionTestsPath=${workspaceFolder}/packages/foam-vscode/out/test/suite/index"
],
"outFiles": [
"${workspaceFolder}/packages/foam-vscode/out/test/**/*.js"
],
"preLaunchTask": "${defaultBuildTask}"
},
{
"name": "Test Core",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/node_modules/tsdx/dist/index.js",
"args": ["test"],
"cwd": "${workspaceFolder}/packages/foam-core",
"internalConsoleOptions": "openOnSessionStart",
"preLaunchTask": "${defaultBuildTask}"
}
]
]
}

15
.vscode/settings.json vendored
View File

@@ -12,20 +12,21 @@
},
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
"typescript.tsc.autoDetect": "off",
"foam.edit.linkReferenceDefinitions": "withExtensions",
"foam.files.ignore": [
"**/.vscode/**/*",
"**/_layouts/**/*",
"**/_site/**/*",
"**/node_modules/**/*"
"**/node_modules/**/*",
"packages/**/*"
],
"editor.defaultFormatter": "esbenp.prettier-vscode",
"prettier.requireConfig": true,
"editor.formatOnSave": true,
"editor.tabSize": 2,
"jest.debugCodeLens.showWhenTestStateIn": [
"fail",
"unknown",
"pass"
],
"gitdoc.enabled": false
"jest.debugCodeLens.showWhenTestStateIn": ["fail", "unknown", "pass"],
"gitdoc.enabled": false,
"jest.autoEnable": false,
"jest.runAllTestsFirst": false,
"search.mode": "reuseEditor"
}

54
.vscode/tasks.json vendored
View File

@@ -1,31 +1,31 @@
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
{
"version": "2.0.0",
"tasks": [
{
"label": "watch: foam-vscode",
"type": "npm",
"script": "start:vscode",
"problemMatcher": "$tsc-watch",
"isBackground": true,
"presentation": {
"reveal": "always"
},
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "test: all packages",
"type": "npm",
"script": "test",
"problemMatcher": [],
"group": {
"kind": "test",
"isDefault": true
},
}
]
"version": "2.0.0",
"tasks": [
{
"label": "watch: foam-vscode",
"type": "npm",
"script": "watch",
"problemMatcher": "$tsc-watch",
"isBackground": true,
"presentation": {
"reveal": "always"
},
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "test: all packages",
"type": "npm",
"script": "test",
"problemMatcher": [],
"group": {
"kind": "test",
"isDefault": true
}
}
]
}

17
LICENSE
View File

@@ -1,6 +1,6 @@
The MIT Licence (MIT)
Copyright 2020 Jani Eväkallio <jani.evakallio@gmail.com>
Copyright 2020 - present Jani Eväkallio <jani.evakallio@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
@@ -17,4 +17,17 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Where noted, some code uses the following license:
MIT License
Copyright (c) 2015 - present Microsoft Corporation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

View File

@@ -14,9 +14,6 @@
// Tons of markdown goodies (lists, tables of content, so much more)
"yzhang.markdown-all-in-one",
// [[wiki-links]], backlinking etc
"kortina.vscode-markdown-notes",
// Graph visualizer
"tchayen.markdown-links",

View File

@@ -3,9 +3,10 @@
Well, that shouldn't have happened!
If you got here via a link from another document, please file an [issue](https://github.com/foambubble/foam/issues) on our GitHub repo including:
- the page you came from
- the link you followed
Thanks!
-The Foam Team
-The Foam Team

View File

@@ -35,4 +35,3 @@ gem "wdm", "~> 0.1.0", :install_if => Gem.win_platform?
# kramdown v2 ships without the gfm parser by default. If you're using
# kramdown v1, comment out this line.
gem "kramdown-parser-gfm"

View File

@@ -203,14 +203,14 @@ GEM
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.3.6)
mini_portile2 (2.5.0)
mini_portile2 (2.5.1)
minima (2.5.1)
jekyll (>= 3.5, < 5.0)
jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1)
minitest (5.14.2)
multipart-post (2.1.1)
nokogiri (1.11.1)
nokogiri (1.11.5)
mini_portile2 (~> 2.5.0)
racc (~> 1.4)
octokit (4.19.0)
@@ -223,7 +223,7 @@ GEM
rb-fsevent (0.10.4)
rb-inotify (0.10.1)
ffi (~> 1.0)
rexml (3.2.4)
rexml (3.2.5)
rouge (3.23.0)
ruby-enum (0.8.0)
i18n

33
docs/LICENSE.txt Normal file
View File

@@ -0,0 +1,33 @@
The MIT Licence (MIT)
Copyright 2020 - present Jani Eväkallio <jani.evakallio@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Where noted, some code uses the following license:
MIT License
Copyright (c) 2015 - present Microsoft Corporation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

View File

@@ -19,21 +19,21 @@ window.addEventListener('DOMContentLoaded', (event) => {
document
.querySelectorAll(".markdown-body a[title]:not([href^=http])")
.forEach((a) => {
// filter to only wiki-links
// filter to only wikilinks
var prev = a.previousSibling;
var next = a.nextSibling;
if (
prev instanceof Text && prev.textContent.endsWith('[') &&
prev instanceof Text && prev.textContent.endsWith('[') &&
next instanceof Text && next.textContent.startsWith(']')
) {
// remove surrounding brackets
prev.textContent = prev.textContent.slice(0, -1);
next.textContent = next.textContent.slice(1);
// add CSS list for styling
a.classList.add('wikilink');
// replace page-link with "Page Title"...
a.innerText = a.title;

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

View File

@@ -12,7 +12,6 @@
- What use cases are we working towards?
-[[todo]] User round table
[//begin]: # "Autogenerated link references for markdown compatibility"
[todo]: dev/todo.md "Todo"
[//end]: # "Autogenerated link references"
[//end]: # "Autogenerated link references"

View File

@@ -118,7 +118,7 @@ the community.
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
<https://www.contributor-covenant.org/version/2/0/code_of_conduct.html>.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
@@ -126,7 +126,5 @@ enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
<https://www.contributor-covenant.org/faq>. Translations are available at
<https://www.contributor-covenant.org/translations>.

View File

@@ -2,19 +2,21 @@
tags: todo, good-first-task
---
# Contribution Guide
Foam is open to contributions of any kind, including but not limited to code, documentation, ideas, and feedback.
This guide aims to help guide new and seasoned contributors getting around the Foam codebase.
## Getting Up To Speed
Before you start contributing we recommend that you read the following links:
- [[principles]] - This document describes the guiding principles behind Foam.
- [[code-of-conduct]] - Rules we hope every contributor aims to follow, allowing everyone to participate in our community!
## Diving In
We understand that diving in an unfamiliar codebase may seem scary,
to make it easier for new contributors we provide some resources:
- [[architecture]] - This document describes the architecture of Foam and how the repository is structured.
You can also see [existing issues](https://github.com/foambubble/foam/issues) and help out!
Finally, the easiest way to help, is to use it and provide feedback by [submitting issues](https://github.com/foambubble/foam/issues/new/choose) or participating in the [Foam Community Discord](https://foambubble.github.io/join-discord/g)!
@@ -31,36 +33,59 @@ If you're interested in contributing, this short guide will help you get things
`yarn install`
3. This project uses [Yarn workspaces](https://classic.yarnpkg.com/en/docs/workspaces/). `foam-vscode` relies on `foam-core`. This means we need to compile it before we do any extension development. From the root, run the command:
3. From the root, run the command:
`yarn build`
You should now be ready to start working!
### Structure of the project
Foam code and documentation live in the monorepo at [foambubble/foam](https://github.com/foambubble/foam/).
- [/docs](https://github.com/foambubble/foam/tree/master/docs): documentation and [[recipes]].
Exceptions to the monorepo are:
- The starter template at [foambubble/foam-template](https://github.com/foambubble/)
- All other [[recommended-extensions]] live in their respective GitHub repos
This project uses [Yarn workspaces](https://classic.yarnpkg.com/en/docs/workspaces/).
Originally Foam had:
- [/packages/foam-core](https://github.com/foambubble/foam/tree/master/packages/foam-core) - Powers the core functionality in Foam across all platforms.
- [/packages/foam-vscode](https://github.com/foambubble/foam/tree/master/packages/foam-vscode) - The core VS Code plugin.
To improve DX we have moved the `foam-core` module into `packages/foam-vscode/src/core`, but from a development point of view it's useful to think of the `foam-vscode/src/core` "submodule" as something that might be extracted in the future.
For all intents and purposes this means two things:
1. nothing in `foam-vscode/src/core` should depend on files outside of this directory
2. code in `foam-vscode/src/core` should NOT depend on `vscode` library
We have kept the yarn workspace for the time being as we might use it to pull out `foam-core` in the future, or we might need it for other packages that the VS Code plugin could depend upon (e.g. currently the graph visualization is inside the module, but it might be pulled out if its complexity increases).
### Testing
Code needs to come with tests.
We use the following convention in Foam:
- *.test.ts are unit tests
- *.spec.ts are integration tests
Also, note that tests in `foam-core` live in the `test` directory.
Tests in `foam-vscode` live alongside the code in `src`.
- `*.test.ts` are unit tests
- `*.spec.ts` are integration tests
Tests live alongside the code in `src`.
### The VS Code Extension
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!
@@ -70,5 +95,6 @@ Feel free to modify and submit a PR if this guide is out-of-date or contains err
[//begin]: # "Autogenerated link references for markdown compatibility"
[principles]: principles.md "Principles"
[code-of-conduct]: code-of-conduct.md "Code of Conduct"
[architecture]: dev/architecture.md "Architecture"
[recipes]: recipes/recipes.md "Recipes"
[recommended-extensions]: recommended-extensions.md "Recommended Extensions"
[//end]: # "Autogenerated link references"

View File

@@ -1,21 +0,0 @@
---
tags: architecture
---
# Architecture
This document aims to provide a quick overview of the Foam architecture!
Foam code and documentation live in the monorepo at [foambubble/foam](https://github.com/foambubble/foam/).
- [/docs](https://github.com/foambubble/foam/tree/master/docs): documentation and [[recipes]].
- [/packages/foam-core](https://github.com/foambubble/foam/tree/master/packages/foam-core) - Powers the core functionality in Foam across all platforms.
- [/packages/foam-vscode](https://github.com/foambubble/foam/tree/master/packages/foam-vscode) - The core VSCode plugin.
Exceptions to the monorepo are:
- The starter template at [foambubble/foam-template](https://github.com/foambubble/)
- All other [[recommended-extensions]] live in their respective GitHub repos.
- [foam-cli](https://github.com/foambubble/foam-cli) - The Foam CLI tool.
[//begin]: # "Autogenerated link references for markdown compatibility"
[recipes]: ../recipes/recipes.md "Recipes"
[recommended-extensions]: ../recommended-extensions.md "Recommended Extensions"
[//end]: # "Autogenerated link references"

View File

@@ -10,5 +10,3 @@ But there's also a bunch of roadmap items that are hard to implement this way, a
Overall, we should strive to build big things from small things. Focused, interoperable modules are better, because they allow users to pick and mix which features work for them. A good example of why this matters is the Markdown All In One extension we rely on: While it provides many of the things we need, a few of its features are incompatible with how I would like to work, and therefore it becomes a limiter of how well I can improve my own workflow.
However, there becomes a point where we may benefit from implementing a centralised solution, e.g. a syntax, an extension or perhaps a VSCode language server. As much as possible, we should allow users to operate in a decentralised manner.

View File

@@ -17,7 +17,7 @@
`foam-core`'s primary responsibility is to build an API on top of a workspace of markdown files, which allows us to:
- Treat files as a graph, based on links
- Can be either [[wiki-links]] or relative `[markdown](links.md)` style
- Can be either [[wikilinks]] or relative `[markdown](links.md)` style
- We need to know about the edges (connections) as well as nodes
- What link points to what other file, etc.
- Needs to have the exact link text, e.g. even if `[[some-page]]` or `[[some-page.md]]` or `[[Some Page]]` point to the same document (`./some-page.md`), we need to know which format was used, so [[link-reference-definitions]] can be generated correctly
@@ -61,7 +61,7 @@ Here are some example use cases that the core should support. They don't need to
- Adding and editing page content
- [[materialized-backlinks]]
- [[link-reference-definitions]] for [[wiki-links]]
- [[link-reference-definitions]] for [[wikilinks]]
- [Frontmatter](https://jekyllrb.com/docs/front-matter/)
- Finding all documents with `#tag`
- Finding all documents with instances of `[[link]]`
@@ -99,7 +99,7 @@ Useful for knowing what needs to be supported. See [[feature-comparison]].
[workspace-janitor]: ../features/workspace-janitor.md "Janitor"
[cli]: ../features/cli.md "Command Line Interface"
[build-vs-assemble]: build-vs-assemble.md "Build vs Assemble"
[wiki-links]: ../wiki-links.md "Wiki Links"
[wikilinks]: ../wikilinks.md "Wikilinks"
[link-reference-definitions]: ../features/link-reference-definitions.md "Link Reference Definitions"
[materialized-backlinks]: materialized-backlinks.md "Materialized Backlinks (stub)"
[todo]: todo.md "Todo"

View File

@@ -1,16 +1,16 @@
# Foam File Format
This file is an example of a valid Foam file. Essentially it's just a markdown file with a bit of additional support for mediawiki-style `[[wiki-links]]`.
This file is an example of a valid Foam file. Essentially it's just a markdown file with a bit of additional support for MediaWiki-style `[[wikilinks]]`.
Here are a few specific constraints, mainly because our tooling is a bit fragmented. Most of these should be eventually lifted, and our requirement should just be "Markdown with `[[wiki-links]]`:
Here are a few specific constraints, mainly because our tooling is a bit fragmented. Most of these should be eventually lifted, and our requirement should just be "Markdown with `[[wikilinks]]`:
- **The first top level `# Heading` will be used as title for the note.**
- If not available, we will use the file name
- **File name should have extension `.md`**
- This is a temporary limitation and will be lifted in future versions.
- At least `.mdx` will be supported, but ideally we'll support any file that you can map to `Markdown` language mode in VS Code
- **In addition to normal Markdown Links syntax you can use `[[media-wiki]]` links.** See [[wiki-links]] for more details.
- **In addition to normal Markdown Links syntax you can use `[[MediaWiki]]` links.** See [[wikilinks]] for more details.
[//begin]: # "Autogenerated link references for markdown compatibility"
[wiki-links]: ../wiki-links.md "Wiki Links"
[wikilinks]: ../wikilinks.md "Wikilinks"
[//end]: # "Autogenerated link references"

View File

@@ -4,13 +4,13 @@
### File-by-file Insertion
For the time being, if you want to get [[wiki-links]] into all files within the workspace, you'll need to generate the link reference definitions yourself file-by-file (with the assistance of Foam).
For the time being, if you want to get [[wikilinks]] into all files within the workspace, you'll need to generate the link reference definitions yourself file-by-file (with the assistance of Foam).
### Wikilinks don't work on GitHub
> **TL;DR;** [workaround](#workaround) in the end of the chapter.
If you click any of the wiki-links on GitHub web UI (such as the `README.md` of a project), you'll notice that the links break with a 404 error.
If you click any of the wikilinks on GitHub web UI (such as the `README.md` of a project), you'll notice that the links break with a 404 error.
At the time of writing (June 28 2020) this is a known, but unsolved error. To understand why this is the case, we need to understand what we are trading off.
@@ -59,7 +59,7 @@ Problem space in essence:
- may clutter the search results
- During build-time (when converting markdown to html for publishing purposes)
- link reference definitions are needed, if the files are published via such tools (or to such platforms) that don't understand wikilinks
- link reference definitions might have to be in different formats depending on the publish target (e.g. Github pages vs Github UI)
- link reference definitions might have to be in different formats depending on the publish target (e.g. GitHub pages vs GitHub UI)
The potential solution:
@@ -72,6 +72,7 @@ The potential solution:
- This would be a GitHub action (or a local script, ran via foam-cli) that outputs publish-friendly markdown format for static site generators and other publishing tools
- This build step should be pluggable, so that other transformations could be ran during it
- Have publish targets defined in settings, that support both turning the link reference definitions on/off and defining their format (.md or not). Example draft (including also edit-time aspect):
```typescript
// settings json
// see enumerations below for explanations on values
@@ -120,8 +121,9 @@ The potential solution:
}
```
- With Foam repo, just use edit-time link reference definitions with '.md' extension - this makes the links work in the Github UI
- Have publish target defined for Github pages, that doesn't use '.md' extension, but still has the link reference definitions. Generate the output into gh-pages branch (or separate repo) with automation.
- With Foam repo, just use edit-time link reference definitions with '.md' extension - this makes the links work in the GitHub UI
- Have publish target defined for GitHub pages, that doesn't use '.md' extension, but still has the link reference definitions. Generate the output into gh-pages branch (or separate repo) with automation.
- This naturally requires first removing the existing link reference definitions during the build
- Other
- To clean up the search results, remove link reference definition section guards (assuming that these are not defined by the markdown spec). Use unifiedjs parse trees to identify if there's missing (or surplus) definitions (check if they are identified properly by the library), and just add the needed definitions to the bottom of the file (without guards) AND remove them if they are not needed (anywhere from the file).
@@ -135,7 +137,7 @@ UI-wise, the publish targets could be picked in some similar fashion as the run/
- [tracking issue on GitHub](https://github.com/foambubble/foam/issues/16)
[//begin]: # "Autogenerated link references for markdown compatibility"
[wiki-links]: ../wiki-links.md "Wiki Links"
[wikilinks]: ../wikilinks.md "Wikilinks"
[link-reference-definitions]: ../features/link-reference-definitions.md "Link Reference Definitions"
[backlinking]: ../features/backlinking.md "Backlinking"
[//end]: # "Autogenerated link references"

View File

@@ -11,8 +11,7 @@ The idea would be to automatically generate lists of backlinks (and optionally,
- Make every link two-way navigable in published sites
- Make Foam notes more portable to different apps and long-term storage
[//begin]: # "Autogenerated link references for markdown compatibility"
[todo]: todo.md "Todo"
[roadmap]: roadmap.md "Roadmap"
[//end]: # "Autogenerated link references"
[//end]: # "Autogenerated link references"

View File

@@ -25,7 +25,7 @@ If a roadmap item is a stub, **consider** opening a [GitHub issue](https://githu
- [[improve-default-workspace-settings]]
- Discussion: [foam#270](https://github.com/foambubble/foam/issues/270)
- Improve [[git-integration]]
- Fix [[wiki-links]] compatibility issues
- Fix [[wikilinks]] compatibility issues
- Simplify [[foam-file-format]]
### Core features
@@ -87,7 +87,7 @@ The community is working on a number of automated scripts to help you migrate to
[recipes]: ../recipes/recipes.md "Recipes"
[contribution-guide]: ../contribution-guide.md "Contribution Guide"
[git-integration]: ../features/git-integration.md "Git Integration"
[wiki-links]: ../wiki-links.md "Wiki Links"
[wikilinks]: ../wikilinks.md "Wikilinks"
[foam-file-format]: foam-file-format.md "Foam File Format"
[unlinked-references]: unlinked-references.md "Unlinked references (stub)"
[make-backlinks-more-prominent]: ../recipes/make-backlinks-more-prominent.md "Make Backlinks More Prominent"

View File

@@ -1,6 +1,6 @@
# Backlinking
When using [[wiki-links]], you can find all notes that link to a specific note in the [VS Code Markdown Notes](https://marketplace.visualstudio.com/items?itemName=kortina.vscode-markdown-notes) **Backlinks Explorer**
When using [[wikilinks]], you can find all notes that link to a specific note in the [VS Code Markdown Notes](https://marketplace.visualstudio.com/items?itemName=kortina.vscode-markdown-notes) **Backlinks Explorer**
- Run `Cmd` + `Shift` + `P` (`Ctrl` + `Shift` + `P` for Windows), type "backlinks" and run the **Explorer: Focus on Backlinks** view.
- Keep this pane always visible to discover relationships between your thoughts
@@ -8,7 +8,7 @@ When using [[wiki-links]], you can find all notes that link to a specific note i
- Finding backlinks in published Foam workspaces via [[materialized-backlinks]] is on the [[roadmap]] but not yet implemented.
[//begin]: # "Autogenerated link references for markdown compatibility"
[wiki-links]: ../wiki-links.md "Wiki Links"
[wikilinks]: ../wikilinks.md "Wikilinks"
[make-backlinks-more-prominent]: ../recipes/make-backlinks-more-prominent.md "Make Backlinks More Prominent"
[materialized-backlinks]: ../dev/materialized-backlinks.md "Materialized Backlinks (stub)"
[roadmap]: ../dev/roadmap.md "Roadmap"

View File

@@ -1,12 +1,14 @@
# Creating New Notes
- Write out a new `[[wiki-link]]` and `Cmd` + `Click` to create a new file and enter it.
- Write out a new `[[wikilink]]` and `Cmd` + `Click` to create a new file and enter it.
- For keyboard navigation, use the 'Follow Definition' key `F12` (or [remap key binding](https://code.visualstudio.com/docs/getstarted/keybindings) to something more ergonomic)
- `Cmd` + `Shift` + `P` (`Ctrl` + `Shift` + `P` for Windows), execute `New Note` from [VS Code Markdown Notes](https://marketplace.visualstudio.com/items?itemName=kortina.vscode-markdown-notes) and enter a **Title Case Name** to create `title-case-name.md`
- `Cmd` + `Shift` + `P` (`Ctrl` + `Shift` + `P` for Windows), execute `Foam: Create New Note` and enter a **Title Case Name** to create `Title Case Name.md`
- Add a keyboard binding to make creating new notes easier.
- The [[note-templates]] used by this command can be customized.
- You shouldn't worry too much about categorizing your notes. You can always [[search-for-notes]], and explore them using the [[graph-visualisation]].
[//begin]: # "Autogenerated link references for markdown compatibility"
[search-for-notes]: ../recipes/search-for-notes.md "Search for Notes"
[graph-visualisation]: graph-visualisation.md "Graph Visualisation"
[note-templates]: note-templates "Note Templates"
[search-for-notes]: ../recipes/search-for-notes "Search for Notes"
[graph-visualisation]: graph-visualisation "Graph Visualisation"
[//end]: # "Autogenerated link references"

View File

@@ -13,3 +13,19 @@ For example, to load a stylesheet called `Style.css`, we can update `settings.js
"markdown.styles": ["Style.css"]
}
```
## Foam elements
### Foam note & placeholder links
It is possible to custom style the links to a note or placeholder. The links are an `<a>` tag. For notes use the class `foam-note-link`, for placeholders use `foam-placeholder-link`.
### Cyclic inclusion warnings
Foams offers the functionality to include other notes in your note. This will be displayed in the preview tab. Foam recognises a cyclic inclusion of notes and will display a warning when detected. The following html is used and can be custom styled using the class `foam-cyclic-link-warning`.
```html
<div class="foam-cyclic-link-warning">
Cyclic link detected for wikilink: ${wikilink}
</div>
```

View File

@@ -25,9 +25,9 @@ The above configuration would create a file `journal/note-2020-07-25.mdx`, with
## Daily Note Templates
In the future, Foam may provide a functionality for specifying a template for new Daily Notes and other types of documents.
Daily notes can also make use of [templates](note-templates.md), by defining a special `.foam/templates/daily-note.md` template.
In the meantime, you can use [VS Code Snippets](https://code.visualstudio.com/docs/editor/userdefinedsnippets) for defining your own Daily Note template.
See [Note Templates](note-templates.md) for details of the features available in templates.
## Roam-style Automatic Daily Notes

View File

@@ -1,60 +0,0 @@
# Foam Local Plugins
Foam can use workspace plugins to provide customization for users.
## ATTENTION
This feature is experimental and its API subject to change.
**Local plugins can execute arbitrary code on your machine** - ensure you trust the content of the repo.
## Goal
Here are some of the things that we could enable with local plugins in Foam:
- extend the document syntax to support roam style attributes (e.g. `stage:: seedling`)
- automatically add tags to my notes based on the location in the repo (e.g. notes in `/areas/finance` will automatically get the `#finance` tag)
- add a new CLI command to support some internal use case or automate import/export
- extend the VSCode experience to support one's own workflow, e.g. weekly note, templates, extra panels, foam model derived TOC, ... all without having to write/deploy a VSCode extension
## How to enable local plugins
Plugins can execute arbitrary code on the client's machine.
For this reason this feature is disabled by default, and needs to be explicitly enabled.
To enable the feature:
- create a `~/.foam/config.json` file
- add the following content to the file
```
{
"experimental": {
"localPlugins": {
"enabled": true
}
}
}
```
For security reasons this setting can only be defined in the user settings file.
(otherwise a malicious repo could set it via its `./foam/config.json`)
- [[todo]] an additional security mechanism would involve having an explicit list of whitelisted repo paths where plugins are allowed. This would provide finer grain control over when to enable or disable the feature.
## Technical approach
When Foam is loaded it will check whether the experimental local plugin feature is enabled, and in such case it will:
- check `.foam/plugins` directory.
- each directory in there is considered a plugin
- the layout of each directory is
- `index.js` contains the main info about the plugin, specifically it exports:
- `name: string` the name of the plugin
- `description?: string` the description of the plugin
- `parser?: ParserPlugin` an object that interacts with the markdown parsing phase
Currently for simplicity we keep everything in one file. We might in the future split the plugin by domain (e.g. vscode, cli, core, ...)
[//begin]: # 'Autogenerated link references for markdown compatibility'
[todo]: ../dev/todo.md 'Todo'
[//end]: # 'Autogenerated link references'

View File

@@ -1,19 +1,21 @@
# Foam logging in VsCode
## Find the Foam log
The Foam log can be found in the `Output` tab.
1. To show the tab, click on `View > Output`.
2. In the dropdown on the right of the tab, select `Foam`.
![Find the foam log](../assets/images/foam-log.png)
## Change the default logging level
1. Open workspace settings (`cmd+,`, or execute the `Preferences: Open Workspace Settings` command)
2. Look for the entry `Foam > Logging: Level`
Set to debug when reporting an issue
## Change the log level for the session
Execute the command `Foam: Set log level`.

View File

@@ -3,6 +3,7 @@
Foam comes with a graph visualisation of your notes. To see the graph execute the `Foam: Show Graph` command.
The graph will:
- allow you to highlight a node by hovering on it, to quickly see how it's connected to the rest of your notes
- allow you to select one or more (by keeping `SHIFT` pressed while selecting) nodes by clicking on them, to better understand the structure of your notes
- allow you to navigate to a note by clicking on it while pressing `CTRL` or `CMD`
@@ -32,6 +33,7 @@ A sample configuration object is provided below:
```
### Style nodes by type
It is possible to customize the style of a node based on the `type` property in the YAML frontmatter of the corresponding document.
For example the following `backlinking.md` note:
@@ -46,6 +48,7 @@ type: feature
```
And the following `settings.json`:
```json
"foam.graph.style": {
"node": {
@@ -57,6 +60,3 @@ And the following `settings.json`:
Will result in the following graph:
![Style node by type](../assets/images/style-node-by-type.png)

View File

@@ -0,0 +1,20 @@
# Including notes in a note
In some situations it might be useful to include the content of another note in your current note. Foam supports this displaying within the vscode environment. Note, this does not work out-of-the-box for your publishing solutions.
## Including a note
Including a note can be done by adding an `!` before a wikilink defintion. For example `![[wikilink]]`.
## Custom styling
Displaying the inclusion of notes allows for some custom styling, see [[custom-markdown-preview-styles]]
## Future possibilities
Work on this feature is evolving and progressing. See the [[inclusion-of-notes]] proposal for the current discussion.
[//begin]: # "Autogenerated link references for markdown compatibility"
[custom-markdown-preview-styles]: custom-markdown-preview-styles.md "Custom Markdown Preview Styles"
[inclusion-of-notes]: ../proposals/inclusion-of-notes.md "Inclusion of notes Proposal "
[//end]: # "Autogenerated link references"

View File

@@ -2,27 +2,31 @@
## Introduction
When you use `[[wiki-links]]`, the [foam-vscode](https://github.com/foambubble/foam/tree/master/packages/foam-vscode) extension will automatically generate [Markdown Link Reference Definitions](https://spec.commonmark.org/0.29/#link-reference-definitions) at the bottom of the file. This is done to make the content of the file compatible with various Markdown tools (e.g. parsers, static site generators, VS code plugins etc), which don't support `[[wiki-links]]`.
When you use `[[wikilinks]]`, the [foam-vscode](https://github.com/foambubble/foam/tree/master/packages/foam-vscode) extension will automatically generate [Markdown Link Reference Definitions](https://spec.commonmark.org/0.29/#link-reference-definitions) at the bottom of the file. This is done to make the content of the file compatible with various Markdown tools (e.g. parsers, static site generators, VS code plugins etc), which don't support `[[wikilinks]]`.
## Example
The following example:
```md
- [[wiki-links]]
- [[wikilinks]]
- [[github-pages]]
```
...generates the following link reference definitions to the bottom of the file:
```md
[wiki-links]: wiki-links "Wiki Links"
[github-pages]: github-pages "Github Pages"
[wikilinks]: wikilinks "Wikilinks"
[github-pages]: github-pages "GitHub Pages"
```
You can open the [raw markdown](https://foambubble.github.io/foam/features/link-reference-definitions.md) to see them at the bottom of this file
## Specification
The three components of a link reference definition are `[link-label]: link-target "Link Title"`
- **link label:** The link text to match in the surrounding markdown document. This matches the inner bracket of the double-bracketed `[[wiki-link]]` notation
- **link label:** The link text to match in the surrounding markdown document. This matches the inner bracket of the double-bracketed `[[wikilink]]` notation
- **link destination** The target of the matched link
- By default we generate links without extension. This can be overridden, see [Configuration](#configuration) below
- **"Link Title"** Optional title for link (The Foam template has a snippet of JavaScript to replace this on the website at runtime)
@@ -67,7 +71,6 @@ After changing the setting in your workspace, you can run the [[workspace-janito
See [[link-reference-definition-improvements]] for further discussion on current problems and potential solutions.
[//begin]: # "Autogenerated link references for markdown compatibility"
[workspace-janitor]: workspace-janitor.md "Janitor"
[todo]: ../dev/todo.md "Todo"

View File

@@ -1,17 +1,188 @@
# Note Templates
Foam supports note templates.
Foam supports note templates. Templates are a way to customize the starting content for your notes (instead of always starting from an empty note).
Note templates live in `.foam/templates`. Run the `Foam: Create New Template` command from the command palette or create a regular `.md` file there to add a template.
Note templates are files located in the special `.foam/templates` directory.
## Quickstart
Create a template:
* Run the `Foam: Create New Template` command from the command palette
* OR manually create a regular `.md` file in the `.foam/templates` directory
![Create new template GIF](../assets/images/create-new-template.gif)
_Theme: Ayu Light_
To create a note from a template, execute the `Foam: Create New Note From Template` command and follow the instructions. Don't worry if you've not created a template yet! You'll be prompted to create a new template if none exist.
To create a note from a template:
* Run the `Foam: Create New Note From Template` command and follow the instructions. Don't worry if you've not created a template yet! You'll be prompted to create a new template if none exist.
* OR run the `Foam: Create New Note` command, which uses the special default template (`.foam/templates/new-note.md`, if it exists)
![Create new note from template GIF](../assets/images/create-new-note-from-template.gif)
_Theme: Ayu Light_
## Special templates
### Default template
The `.foam/templates/new-note.md` template is special in that it is the template that will be used by the `Foam: Create New Note` command.
Customize this template to contain content that you want included every time you create a note.
### Default daily note template
The `.foam/templates/daily-note.md` template is special in that it is the template that will be used when creating daily notes (e.g. by using `Foam: Open Daily Note`).
Customize this template to contain content that you want included every time you create a daily note.
## Variables
Templates can use all the variables available in [VS Code Snippets](https://code.visualstudio.com/docs/editor/userdefinedsnippets#_variables).
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. |
| `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. 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
Templates can also contain metadata about the templates themselves. The metadata is defined in YAML "Frontmatter" blocks within the templates.
| Name | Description |
| ------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `filepath` | The filepath to use when creating the new note. If the filepath is a relative filepath, it is relative to the current workspace. |
| `name` | A human readable name to show in the template picker. |
| `description` | A human readable description to show in the template picker. |
Foam-specific variables (e.g. `$FOAM_TITLE`) can be used within template metadata. However, VS Code snippet variables are ([currently](https://github.com/foambubble/foam/pull/655)) not supported.
### `filepath` attribute
The `filepath` metadata attribute allows you to define a relative or absolute filepath to use when creating a note using the template.
If the filepath is a relative filepath, it is relative to the current workspace.
**Note:** While you can make use of the `filepath` attribute in [daily note](daily-notes.md) templates (`.foam/templates/daily-note.md`), there is currently no way to have `filepath` vary based on the date. This will be improved in the future. For now, you can customize the location of daily notes using the [`foam.openDailyNote` settings](daily-notes.md).
#### Example of relative `filepath`
For example, `filepath` can be used to customize `.foam/templates/new-note.md`, overriding the default `Foam: Create New Note` behaviour of opening the file in the same directory as the active file:
```yaml
---
# This will create the note in the "journal" subdirectory of the current workspace,
# regardless of which file is the active file.
foam_template:
filepath: 'journal/$FOAM_TITLE.md'
---
```
#### Example of absolute `filepath`
`filepath` can be an absolute filepath, so that the notes get created in the same location, regardless of which file or workspace the editor currently has open.
The format of an absolute filepath may vary depending on the filesystem used.
```yaml
---
foam_template:
# Unix / MacOS filesystems
filepath: '/Users/john.smith/foam/journal/$FOAM_TITLE.md'
# Windows filesystems
filepath: 'C:\Users\john.smith\Documents\foam\journal\$FOAM_TITLE.md'
---
```
### `name` and `description` attributes
These attributes provide a human readable name and description to be shown in the template picker (e.g. When a user uses the `Foam: Create New Note From Template` command):
![Template Picker annotated with attributes](../assets/images/template-picker-annotated.png)
### Adding template metadata to an existing YAML Frontmatter block
If your template already has a YAML Frontmatter block, you can add the Foam template metadata to it.
#### Limitations
Foam only supports adding the template metadata to *YAML* Frontmatter blocks. If the existing Frontmatter block uses some other format (e.g. JSON), you will have to add the template metadata to its own YAML Frontmatter block.
Further, the template metadata must be provided as a [YAML block mapping](https://yaml.org/spec/1.2/spec.html#id2798057), with the attributes placed on the lines immediately following the `foam_template` line:
```yaml
---
existing_frontmatter: "Existing Frontmatter block"
foam_template: # this is a YAML "Block" mapping ("Flow" mappings aren't supported)
name: My Note Template # Attributes must be on the lines immediately following `foam_template`
description: This is my note template
filepath: `journal/$FOAM_TITLE.md`
---
This is the rest of the template
```
Due to the technical limitations of parsing the complex YAML format, unless the metadata is provided this specific form, Foam is unable to correctly remove the template metadata before creating the resulting note.
If this limitation proves inconvenient to you, please let us know. We may be able to extend our parsing capabilities to cover your use case. In the meantime, you can add the template metadata without this limitation by providing it in its own YAML Frontmatter block.
### Adding template metadata to its own YAML Frontmatter block
You can add the template metadata to its own YAML Frontmatter block at the start of the template:
```yaml
---
foam_template:
name: My Note Template
description: This is my note template
filepath: `journal/$FOAM_TITLE.md`
---
This is the rest of the template
```
If the note already has a Frontmatter block, a Foam-specific Frontmatter block can be added to the start of the template. The Foam-specific Frontmatter block must always be placed at the very beginning of the file, and only whitespace can separate the two Frontmatter blocks.
```yaml
---
foam_template:
name: My Note Template
description: This is my note template
filepath: `journal/$FOAM_TITLE.md`
---
---
existing_frontmatter: "Existing Frontmatter block"
---
This is the rest of the template
```

View File

@@ -3,15 +3,22 @@
Foam supports tags.
## Creating a tag
There are two ways of creating a tag:
- adding a `#tag` anywhere in the text of the note
- using the `tags: tag1, tag2` property in frontmatter
Tags can also be hierarchical, so you can have `#parent/child`.
## Navigating tags
It's possible to navigate tags via the Tag Explorer panel.
In the future it will be possible to explore tags via the graph as well.
## Styling tags
Inline tags can be styled using custom CSS with the selector `.foam-tag`.
## An alternative to tags
Given the power of backlinks, some people prefer to use them also as tags.

View File

@@ -5,10 +5,12 @@ To store your personal knowledge graph in markdown files instead of a database,
**Foam Janitor** (inspired by Andy Matuschak's [note-link-janitor](https://github.com/andymatuschak/note-link-janitor)) helps you migrate existing notes to Foam, and maintain your Foam's health over time.
Currently, Foam's Janitor helps you to:
- Ensure your [[link-reference-definitions]] are up to date
- Ensure every document has a well-formatted title (required for Markdown Links, Markdown Notes, and Foam Gatsby Template compatibility)
In the future, Janitor can help you with
- Updating [[materialized-backlinks]]
- Lint, format and structure notes
- Rename and move notes around while keeping their references up to date.

View File

@@ -4,15 +4,19 @@
- [Frequently Asked Questions](#frequently-asked-questions)
- [Links/Graphs/BackLinks don't work. How do I enable them?](#linksgraphsbacklinks-dont-work-how-do-i-enable-them)
- [I don't want Foam enabled for all my workspaces](#i-dont-want-foam-enabled-for-all-my-workspaces)
## Links/Graphs/BackLinks don't work. How do I enable them?
- Ensure that you have all the [[recommended-extensions]] installed in Visual Studio Code
- Reload Visual Studio Code by running `Cmd` + `Shift` + `P` (`Ctrl` + `Shift` + `P` for Windows), type "reload" and run the **Developer: Reload Window** command to for the updated extensions take effect
- Check the formatting rules for links on [[foam-file-format]], [[wiki-links]] and [[link-formatting-and-autocompletion]]
- Check the formatting rules for links on [[foam-file-format]], [[wikilinks]] and [[link-formatting-and-autocompletion]]
## I don't want Foam enabled for all my workspaces
Any extension you install in Visual Studio Code is enabled by default. Give the philosophy of Foam it works out of the box without doing any configuration upfront. In case you want to disable Foam for a specific workspace, or disable Foam by default and enable it for specific workspaces, it is advised to follow the best practices as [documented by Visual Studio Code](https://code.visualstudio.com/docs/editor/extension-marketplace#_manage-extensions)
[//begin]: # "Autogenerated link references for markdown compatibility"
[recommended-extensions]: recommended-extensions.md "Recommended Extensions"
[foam-file-format]: dev/foam-file-format.md "Foam File Format"
[wiki-links]: wiki-links.md "Wiki Links"
[wikilinks]: wikilinks.md "Wikilinks"
[//end]: # "Autogenerated link references"

View File

@@ -5,7 +5,7 @@ Uncategorised thoughts, to be added
- Release notes
- Markdown Preview
- It's possible to customise the markdown preview styling. **Maybe make it use local foam workspace styles for live preview of the site??**
- See: https://marketplace.visualstudio.com/items?itemName=bierner.markdown-preview-github-styles
- See: <https://marketplace.visualstudio.com/items?itemName=bierner.markdown-preview-github-styles>
- Use VS Code [CodeTour](https://marketplace.visualstudio.com/items?itemName=vsls-contrib.codetour) for onboarding
- Investigate other similar extensions:
- [Unotes](https://marketplace.visualstudio.com/items?itemName=ryanmcalister.Unotes)
@@ -16,10 +16,10 @@ Uncategorised thoughts, to be added
- Every Foam could have a different theme even in the editor, so you'll see it like they see it
- UI and layout design of your workspace can become a thing
- VS Code Notebooks API
- https://code.visualstudio.com/api/extension-guides/notebook
- <https://code.visualstudio.com/api/extension-guides/notebook>
- Future architecture
- Could we do publish-related settings as a pre-push git hook, e.g. generating footnote labels
- Running them on Github Actions to edit stuff as it comes in
- Running them on GitHub Actions to edit stuff as it comes in
- Ideally, we shouldn't have to touch files, should be just markdown
- Looking at the errors/warnings/output panes makes me think, what kind of automated quality tools could we write.
- Deduplication, finding similarities...
@@ -32,5 +32,3 @@ Uncategorised thoughts, to be added
- Maps have persistent topologies. As the graph grows, you should be able to visualise where an idea belongs. Maybe a literal map? And island? A DeckGL visualisation?
Testing: This file is served from the /docs directory.

View File

@@ -37,7 +37,7 @@ Whether you want to build a [Second Brain](https://www.buildingasecondbrain.com/
1. Create a single **Foam** workspace for all your knowledge and research following the [Getting started](#getting-started) guide.
2. Write your thoughts in markdown documents (I like to call them **Bubbles**, but that might be more than a little twee). These documents should be atomic: Put things that belong together into a single document, and limit its content to that single topic. ([source](https://zettelkasten.de/posts/overview/#principles))
3. Use Foam's shortcuts and autocompletions to link your thoughts together with `[[wiki-links]]`, and navigate between them to explore your knowledge graph.
3. Use Foam's shortcuts and autocompletions to link your thoughts together with `[[wikilinks]]`, and navigate between them to explore your knowledge graph.
4. Get an overview of your **Foam** workspace using a [[graph-visualisation]] (⚠️ WIP), and discover relationships between your thoughts with the use of [[backlinking]].
Foam is a like a bathtub: _What you get out of it depends on what you put into it._
@@ -48,7 +48,7 @@ Like the soapy suds it's named after, **Foam** is mostly air.
1. The editing experience of **Foam** is powered by VS Code, enhanced by workspace settings that glue together [[recommended-extensions]] and preferences optimised for writing and navigating information.
2. To back up, collaborate on and share your content between devices, Foam pairs well with [GitHub](http://github.com/).
3. To publish your content, you can set it up to publish to [GitHub Pages](https://pages.github.com/) with zero code and zero config, or to any website hosting platform like [Netlify](http://netlify.com/) or [Vercel](https://vercel.com).
3. To publish your content, you can set it up to publish to [GitHub Pages](https://pages.github.com/), or to any website hosting platform like [Netlify](http://netlify.com/) or [Vercel](https://vercel.com).
> **Fun fact**: This documentation was researched, written and published using **Foam**.
@@ -66,12 +66,14 @@ These instructions assume you have a GitHub account, and you have Visual Studio
2. [Clone the repository locally](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/cloning-a-repository) and open it in VS Code.
*Open the repository as a folder using the `File > Open...` menu item. In VS Code, "open workspace" refers to [multi-root workspaces](https://code.visualstudio.com/docs/editor/multi-root-workspaces).*
*Open the repository as a folder using the `File > Open...` menu item. In VS Code, "open workspace" refers to [multi-root workspaces](https://code.visualstudio.com/docs/editor/multi-root-workspaces).*
3. When prompted to install recommended extensions, click **Install all** (or **Show Recommendations** if you want to review and install them one by one)
After setting up the repository, open `.vscode/settings.json` and edit, add or remove any settings you'd like for your Foam workspace.
* *If using a [multi-root workspace](https://code.visualstudio.com/docs/editor/multi-root-workspaces) as noted above, make sure that your **Foam** directory is first in the list. There are some settings that will need to be migrated from `.vscode/settings.json` to your `.code-workspace` file.*
To learn more about how to use **Foam**, read the [[recipes]].
Getting stuck in the setup? Read the [[frequently-asked-questions]].
@@ -194,6 +196,28 @@ If that sounds like something you're interested in, I'd love to have you along o
<td align="center"><a href="https://movermeyer.com"><img src="https://avatars.githubusercontent.com/u/1459385?v=4?s=60" width="60px;" alt=""/><br /><sub><b>Michael Overmeyer</b></sub></a><br /><a href="https://github.com/foambubble/foam/commits?author=movermeyer" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/derrickqin"><img src="https://avatars.githubusercontent.com/u/3038111?v=4?s=60" width="60px;" alt=""/><br /><sub><b>Derrick Qin</b></sub></a><br /><a href="https://github.com/foambubble/foam/commits?author=derrickqin" title="Documentation">📖</a></td>
<td align="center"><a href="https://www.linkedin.com/in/zomars/"><img src="https://avatars.githubusercontent.com/u/3504472?v=4?s=60" width="60px;" alt=""/><br /><sub><b>Omar López</b></sub></a><br /><a href="https://github.com/foambubble/foam/commits?author=zomars" title="Documentation">📖</a></td>
<td align="center"><a href="http://robincn.com"><img src="https://avatars.githubusercontent.com/u/1583193?v=4?s=60" width="60px;" alt=""/><br /><sub><b>Robin King</b></sub></a><br /><a href="https://github.com/foambubble/foam/commits?author=RobinKing" title="Code">💻</a></td>
</tr>
<tr>
<td align="center"><a href="http://twitter.com/deegovee"><img src="https://avatars.githubusercontent.com/u/4730170?v=4?s=60" width="60px;" alt=""/><br /><sub><b>Dheepak </b></sub></a><br /><a href="https://github.com/foambubble/foam/commits?author=dheepakg" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/daniel-vera-g"><img src="https://avatars.githubusercontent.com/u/28257108?v=4?s=60" width="60px;" alt=""/><br /><sub><b>Daniel VG</b></sub></a><br /><a href="https://github.com/foambubble/foam/commits?author=daniel-vera-g" title="Documentation">📖</a></td>
<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>
<td align="center"><a href="http://rafaelriedel.de"><img src="https://avatars.githubusercontent.com/u/41793?v=4?s=60" width="60px;" alt=""/><br /><sub><b>Rafael Riedel</b></sub></a><br /><a href="https://github.com/foambubble/foam/commits?author=rafo" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/Pearcekieser"><img src="https://avatars.githubusercontent.com/u/5055971?v=4?s=60" width="60px;" alt=""/><br /><sub><b>Pearcekieser</b></sub></a><br /><a href="https://github.com/foambubble/foam/commits?author=Pearcekieser" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/theowenyoung"><img src="https://avatars.githubusercontent.com/u/62473795?v=4?s=60" width="60px;" alt=""/><br /><sub><b>Owen Young</b></sub></a><br /><a href="https://github.com/foambubble/foam/commits?author=theowenyoung" title="Documentation">📖</a> <a href="#content-theowenyoung" title="Content">🖋</a></td>
<td align="center"><a href="http://www.prashu.com"><img src="https://avatars.githubusercontent.com/u/476729?v=4?s=60" width="60px;" alt=""/><br /><sub><b>Prashanth Subrahmanyam</b></sub></a><br /><a href="https://github.com/foambubble/foam/commits?author=ksprashu" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/JonasSprenger"><img src="https://avatars.githubusercontent.com/u/25108895?v=4?s=60" width="60px;" alt=""/><br /><sub><b>Jonas SPRENGER</b></sub></a><br /><a href="https://github.com/foambubble/foam/commits?author=JonasSprenger" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/Laptop765"><img src="https://avatars.githubusercontent.com/u/1468359?v=4?s=60" width="60px;" alt=""/><br /><sub><b>Paul</b></sub></a><br /><a href="https://github.com/foambubble/foam/commits?author=Laptop765" title="Documentation">📖</a></td>
<td align="center"><a href="https://bandism.net/"><img src="https://avatars.githubusercontent.com/u/22633385?v=4?s=60" width="60px;" alt=""/><br /><sub><b>Ikko Ashimine</b></sub></a><br /><a href="https://github.com/foambubble/foam/commits?author=eltociear" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/memeplex"><img src="https://avatars.githubusercontent.com/u/2845433?v=4?s=60" width="60px;" alt=""/><br /><sub><b>memeplex</b></sub></a><br /><a href="https://github.com/foambubble/foam/commits?author=memeplex" title="Code">💻</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/AndreiD049"><img src="https://avatars.githubusercontent.com/u/52671223?v=4?s=60" width="60px;" alt=""/><br /><sub><b>AndreiD049</b></sub></a><br /><a href="https://github.com/foambubble/foam/commits?author=AndreiD049" title="Code">💻</a></td>
</tr>
</table>
@@ -208,7 +232,7 @@ If that sounds like something you're interested in, I'd love to have you along o
## License
Foam is licensed under the [MIT license](license).
Foam is licensed under the [MIT license](LICENSE.txt).
[//begin]: # "Autogenerated link references for markdown compatibility"
[graph-visualisation]: features/graph-visualisation.md "Graph Visualisation"

View File

@@ -13,6 +13,7 @@ Present: @jevakallio, @riccardoferretti
- Land work to master
- Create a foam-core package
-
### Open questions

View File

@@ -37,7 +37,7 @@ This principle may seem like it contradicts [Foam wants you to own your thoughts
- **Foam is a collection of ideas.** Foam was released to the public not to share the few good ideas in it, but to learn many good ideas from others. As you improve your own workflow, share your work on your own Foam blog.
- **Foam is open for contributions.** If you use a tool or workflow that you like that fits these principles, please contribute them back to the Foam template as [[recipes]], [[recommended-extensions]] or documentation in [this workspace](https://github.com/foambubble/foam). See also: [[contribution-guide]].
- **Foam is open source.** Feel free to fork it, improve it and remix it. Just don't sell it, as per our [license](license).
- **Foam is open source.** Feel free to fork it, improve it and remix it. Just don't sell it, as per our [license](LICENSE.txt).
- **Foam is not Roam.** This project was inspired by Roam Research, but we're not limited by what Roam does. No idea is too big (though if it doesn't fit with Foam's core workflow, we might make it a [[recipes]] page instead).
## Foam is for hackers, not only for programmers
@@ -48,7 +48,6 @@ While Foam uses tools popular among computer programmers, Foam should be inclusi
- **Foam is not just for programmers.** If you're a programmer, feel free to write scripts and extensions to support your own workflow, and publish them for others to use, but the out of the box Foam experience should not require you to know how to do so. You should, however, be curious and open to adopting new tools that are unfamiliar to you, and evaluate whether they could work for you.
- **Foam is for everyone** As a foam user, you support everyone's quest for knowledge and self-improvement, not only your own, or folks' who look like you. All participants in Foam repositories, discussion forums, physical and virtual meeting spaces etc are expected to respect each other as described in our [[code-of-conduct]]. **Foam is not for toxic tech bros.**
[//begin]: # "Autogenerated link references for markdown compatibility"
[recipes]: recipes/recipes.md "Recipes"
[recommended-extensions]: recommended-extensions.md "Recommended Extensions"

View File

@@ -0,0 +1,48 @@
# Inclusion of notes Proposal <!-- omit in TOC -->
Currently it is not possible within Foam to include other notes into a note. Next to including a full note it could be interesting to add functionalities that allow for greater flexibility. This proposal discusses some functionalities around inclusion of notes.
**IMPORTANT: This design is merely a proposal of a design that could be implemented. It DOES NOT represent a commitment by `Foam` developers to implement the features outlined in this document. This document is merely a mechanism to facilitate discussion of a possible future direction for `Foam`.**
- [Introduction](#introduction)
- [New features](#new-features)
- [Including a note](#including-a-note)
- [Include a section of a note](#include-a-section-of-a-note)
- [Include an attribute of a file (note property or frontmatter)](#include-an-attribute-of-a-file-note-property-or-frontmatter)
## Introduction
Initial work and thought on including a note was ignited by issue [#652](https://github.com/foambubble/foam/issues/652). Requested by a user was a likewise functionality as offered in Obsidian. This was simply the ability to include a note.
Whilst researching digital gardening for my own setup, I came across an in-depth overview by [Maggie Appleton](https://maggieappleton.com/roam-garden). Showing examples of her personal Roam Research I see valuable possibilites to connect more information, if we would add additional functionalities to the possibility of including a note. This proposal displays these possible functionalities and markup.
## New features
### Including a note
The minimal functionality is the ability to fully include a note. Markup used in Obsidian for this is `![[wikilink]]`. For Foam I would suggest to follow this syntax. Benefits being:
- Adds minimal amount of knowledge required as syntax is based on the syntax of creating a wikilink.
- Makes the auto-complete work ouf-of-the-box, without any additional code and listeners required.
**Important**. A risk exists that a loop of including the same notes arises. E.g. Note A includes note B which includes note A. This needs to be prevented by the implementation and made visible to the user.
### Include a section of a note
It could be interesting to only include a section of a note instead of the entire note. In order to do so thse user should be able to use the following syntax:
`![[wikilink#section-b]]`
As a result it will include the section title + section content until the next section *or* end of file.
### Include an attribute of a file (note property or frontmatter)
As a user I could be interested in collecting the value of any given proeprty for a note. For example, I might want to include the tags as defined in the frontmatter of note A. This should be possible via the syntax:
`![[wikilink:<property>]]`
The property value should be lookedup by foam defined properties, e.g. title, **or** any property defined in the frontmatter of a note.
So, the example of including the tags of a note should be:
`![[wikilink:tags]]`

View File

@@ -0,0 +1,329 @@
# Templates v2 Proposal <!-- omit in TOC -->
The current capabilities of templates is limited in some important ways. This document aims to propose a design that addresses these shortcomings.
**IMPORTANT: This design is merely a proposal of a design that could be implemented. It DOES NOT represent a commitment by `Foam` developers to implement the features outlined in this document. This document is merely a mechanism to facilitate discussion of a possible future direction for `Foam`.**
- [Introduction](#introduction)
- [Limitations of current templating](#limitations-of-current-templating)
- [Too much friction to create a new note](#too-much-friction-to-create-a-new-note)
- [Manual note creation (Mouse + Keyboard)](#manual-note-creation-mouse--keyboard)
- [Manual note creation (Keyboard)](#manual-note-creation-keyboard)
- [Foam missing note creation](#foam-missing-note-creation)
- [`Markdown Notes: New Note` (Keyboard)](#markdown-notes-new-note-keyboard)
- [Foam template note creation (Keyboard)](#foam-template-note-creation-keyboard)
- [Templating of daily notes](#templating-of-daily-notes)
- [Templating of filepaths](#templating-of-filepaths)
- [Goal / Philosophy](#goal--philosophy)
- [Proposal](#proposal)
- [Summary](#summary)
- [Add a `${title}` and `${titleSlug}` template variables](#add-a-title-and-titleslug-template-variables)
- [Add a `Foam: Create New Note` command and hotkey](#add-a-foam-create-new-note-command-and-hotkey)
- [Case 1: `.foam/templates/new-note.md` doesn't exist](#case-1-foamtemplatesnew-notemd-doesnt-exist)
- [Case 2: `.foam/templates/new-note.md` exists](#case-2-foamtemplatesnew-notemd-exists)
- [Change missing wikilinks to use the default template](#change-missing-wikilinks-to-use-the-default-template)
- [Add a metadata section to templates](#add-a-metadata-section-to-templates)
- [Example](#example)
- [Add a replacement for `dateFormat`](#add-a-replacement-for-dateformat)
- [Add support for daily note templates](#add-support-for-daily-note-templates)
- [Eliminate all `foam.openDailyNote` settings](#eliminate-all-foamopendailynote-settings)
- [Summary: resulting behaviour](#summary-resulting-behaviour)
- [`Foam: Create New Note`](#foam-create-new-note)
- [`Foam: Open Daily Note`](#foam-open-daily-note)
- [Navigating to missing wikilinks](#navigating-to-missing-wikilinks)
- [`Foam: Create Note From Template`](#foam-create-note-from-template)
- [Extensions](#extensions)
- [More variables in templates](#more-variables-in-templates)
- [`defaultFilepath`](#defaultfilepath)
- [Arbitrary hotkey -> template mappings?](#arbitrary-hotkey---template-mappings)
## Introduction
Creating of new notes in Foam is too cumbersome and slow. Despite their power, Foam templates can currently only be used in very limited scenarios.
This proposal aims to address these issues by streamlining note creation and by allowing templates to be used everywhere.
## Limitations of current templating
### Too much friction to create a new note
Creating new notes should an incredibly streamlined operation. There should be no friction to creating new notes.
Unfortunately, all of the current methods for creating notes are cumbersome.
#### Manual note creation (Mouse + Keyboard)
1. Navigate to the directory where you want the note
2. Click the new file button
3. Provide a filename
4. Manually enter the template contents you want
#### Manual note creation (Keyboard)
1. Navigate to the directory where you want the note
2. `⌘N` to create a new file
3. `⌘S` to save the file and give it a filename
4. Manually enter the template contents you want
#### Foam missing note creation
1. Open an existing note in the directory where you want the note
2. Use the wikilinks syntax to create a link to the title of the note you want to have
3. Use `Ctrl+Click`/`F12` to create the new file
4. Manually enter the template contents you want
#### `Markdown Notes: New Note` (Keyboard)
1. Navigate to the directory where you want the note
2. `Shift+⌘P` to open the command pallette
3. Type `New Note` until it appears in the list. Press `Enter/Return` to select it.
4. Enter a title for the note
5. Manually enter the template contents you want
#### Foam template note creation (Keyboard)
1. `Shift+⌘P` to open the command pallette
2. Type `Create New Note From Template` until it appears in the list. Press `Enter/Return` to select it.
3. Use the arrow keys (or type the template name) to select the template. Press `Enter/Return` to select it.
4. Modify the filepath to match the desired directory + filename. Press `Enter/Return` to select it.
All of these steps are far too cumbersome. And only the last one allows the use of templates.
### Templating of daily notes
Currently `Open Daily Note` opens an otherwise empty note, with a title defined by the `foam.openDailyNote.titleFormat` setting.
Daily notes should be able to be fully templated as well.
### Templating of filepaths
As discussed in ["Template the filepath in `openDailyNote`"](https://github.com/foambubble/foam/issues/523), it would be useful to be able to specify the default filepaths of templates. For example, many people include timestamps in their filepaths.
## Goal / Philosophy
In a sentence: **Creating a new note should be a single button press and should use templates.**
## Proposal
1. Add a new `Foam: Create New Note` that is the streamlined counterpart to the more flexible `Foam: Create New Note From Template`
2. Use templates everywhere
3. Add metadata into the actual templates themselves in order to template the filepaths themselves.
### Summary
This can be done through a series of changes to the way that templates are implemented:
1. Add a `${title}` and `${titleSlug}` template variables
2. Add a `Foam: Create New Note` command and hotkey
3. Change missing wikilinks to use the default template
4. Add a metadata section to templates
5. Add a replacement for `dateFormat`
6. Add support for daily note templates
7. Eliminate all `foam.openDailyNote` settings
I've broken it out into these steps to show that the overall proposal can be implemented piecemeal in independent PRs that build on one another.
### Add a `${title}` and `${titleSlug}` template variables
When you use `Markdown Notes: New Note`, and give it a title, the title is formatted as a filename and also used as the title in the resulting note.
**Example:**
Given the title `Living in a dream world` to `Markdown Notes: New Note`, the filename is `living-in-a-dream-world.md` and the file contents are:
```markdown
# Living in a dream world
```
When creating a note from a template in Foam, you should be able to use a `${title}` variable. If the template uses the `${title}` variable, the user will be prompted for a title when they create a note from a template.
Example:
Given this `.foam/templates/my_template.md` template that uses the `${title}` variable:
```markdown
# ${title}
```
When a user asks for a new note using this template (eg. `Foam: Create New Note From Template`), VSCode will first ask the user for a title then provide it to the template, producing:
```markdown
# Living in a dream world
```
There will also be a `${titleSlug}` variable made available, which will be the "slugified" version of the title (eg. `living-in-a-dream-world`). This will be useful in later steps where we want to template the filepath of a template.
### Add a `Foam: Create New Note` command and hotkey
Instead of using `Markdown Notes: New Note`, Foam itself will have a `Create New Note` command that creates notes using templates.
This would open use the template found at `.foam/templates/new-note.md` to create the new note.
`Foam: Create New Note` will offer the fastest workflow for creating a note when you don't need customization, while `Foam: Create New Note From Template` will remain to serve a fully customizable (but slower) workflow.
#### Case 1: `.foam/templates/new-note.md` doesn't exist
If `.foam/templates/new-note.md` doesn't exist, it behaves the same as `Markdown Notes: New Note`:
* it would ask for a title and create the note in the current directory. It would open a note with the note containing the title.
**Note:** this would use an implicit default template, making use of the `${title}` variable.
#### Case 2: `.foam/templates/new-note.md` exists
If `.foam/templates/new-note.md` exists:
* it asks for the note title and creates the note in the current directory
**Progress:** At this point, we have a faster way to create new notes from templates.
### Change missing wikilinks to use the default template
Clicking on a dangling/missing wikilink should be equivalent to calling `Foam: Create New Note` with the contents of the link as the title.
That way, creating a note by navigating to a missing note uses the default template.
### Add a metadata section to templates
* The `Foam: New Note` command creates a new note in the current directory. This is a sensible default that makes it quick, but lacks flexibility.
* The `Foam: Create New Note From Template` asks the user to confirm/customize the filepath. This is more flexible but slower since there are more steps involved.
Both commands use templates. It would be nice if we could template the filepaths as well as the template contents (See ["Template the filepath in `openDailyNote`"](https://github.com/foambubble/foam/issues/523) for a more in-depth discussion the benefits of filepath templating).
In order to template the filepath, there needs to be a place where metadata like this can be specified.
I think this metadata should be stored alongside the templates themselves. That way, it can make use of all the same template variable available to the templates themselves.
Conceptually, adding metadata to the templates is similar to Markdown frontmatter, though the choice of exact syntax for adding this metadata will have to be done with care since the templates can contain arbitrary contents including frontmatter.
#### Example
A workable syntax is still to be determined.
While this syntax probably doesn't work as a solution, for this example I will demonstrate the concept using a second frontmatter block:
```markdown
<!-- The below front-matter block is for foam-specific template settings -->
<!-- It is removed when the user creates a new note using this template -->
---
<!-- The default filepath to use when using this template -->
<!-- Relative paths are relative to the workspace, absolute paths are absolute -->
<!-- Note that you can include VSCode snippet variables to template the path -->
filepath: `journal/${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE}_${titleSlug}.md`
---
<!-- The actual contents of the template begin after the `---` thematic break immediately below this line-->
---
---
created: ${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE}T${CURRENT_HOUR}:${CURRENT_MINUTE}:${CURRENT_SECOND}
tags: []
---
# ${title}
```
In this example, using this template improves the UX:
In `Foam: Create New Note` workflow, having `filepath` metadata within `.foam/templates/new-note.md` allows for control over the filepath without having to introduce any more UX steps to create a new note. It's still just a hotkey away and a title.
As we'll see, when it comes to allowing daily notes to be templated, we don't even need to use `${title}` in our template, in which case we don't we don't even need to prompt for a title.
In the `Create New Note From Template` workflow, during the step where we allow the user to customize the filepath, it will already templated according to the `filepath` in the template's metadata. This means that the user has to make fewer changes to the path, especially in cases where they want to include things like datetimes in the filenames. This makes it faster (eg. don't have to remember what day it is, and don't have to type it) and less error-prone (eg. when they accidentally type the wrong date).
### Add a replacement for `dateFormat`
`foam.openDailyNote.filenameFormat` uses `dateFormat()` to put the current timestamp into the daily notes filename. This is much more flexible than what is available in VSCode Snippet variables. Before daily notes are switched over to use templates, we will have to come up with another mechanism/syntax to allow for calls to `dateFormat()` within template files.
This would be especially useful in the migration of users to the new daily notes templates. For example, if `.foam/templates/daily-note.md` is unset, then we could generate an implicit template for use by `Foam: Open Daily Note`. Very roughly something like:
```markdown
<!-- The below front-matter block is for foam-specific template settings -->
<!-- It is removed when the user creates a new note using this template -->
---
<!-- The default filepath to use when using this template -->
<!-- Relative paths are relative to the workspace, absolute paths are absolute -->
<!-- Note that you can include VSCode snippet variables to template the path -->
filepath: `${foam.openDailyNote.directory}/${foam.openDailyNote.filenameFormat}.${foam.openDailyNote.fileExtension}`
---
<!-- The actual contents of the template begin after the `---` thematic break immediately below this line-->
---
# ${foam.openDailyNote.titleFormat}
```
### Add support for daily note templates
With the above features implemented, making daily notes use templates is simple.
We define a `.foam/templates/daily-note.md` filepath that the `Foam: Open Daily Note` command will always use to find its daily note template.
If `.foam/templates/daily-note.md` does not exist, it falls back to a default, implicitly defined daily notes template (which follows the default behaviour of the current `foam.openDailyNote` settings).
Both `Foam: Open Daily Note` and `Foam: Create New Note` can share all of the implementation code, with the only differences being the hotkeys used and the template filepath used.
Example daily note template (again using the example syntax of the foam-specific frontmatter block):
```markdown
<!-- The below front-matter block is for foam-specific template settings -->
<!-- It is removed when the user creates a new note using this template -->
---
<!-- The default filepath to use when using this template -->
<!-- Relative paths are relative to the workspace, absolute paths are absolute -->
<!-- Note that you can include VSCode snippet variables to template the path -->
filepath: `journal/${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE}.md`
---
<!-- The actual contents of the template begin after the `---` thematic break immediately below this line-->
---
# ${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE}
```
Since there is no use of the `${title}` variable, opening the daily note behaves exactly as it does today and automatically opens the note with no further user interaction.
### Eliminate all `foam.openDailyNote` settings
Now that all of the functionality of the `foam.openDailyNote` settings have been obviated, these settings can be removed:
* `foam.openDailyNote.directory`, `foam.openDailyNote.filenameFormat`, and `foam.openDailyNote.fileExtension` can be specified in the `filepath` metadata of the daily note template.
* `foam.openDailyNote.titleFormat` has been replaced by the ability to fully template the daily note, including the title.
## Summary: resulting behaviour
### `Foam: Create New Note`
A new command optimized for speedy creation of new notes. This will become the default way to create new notes. In its fastest form, it simply opens the new note with no further user interaction.
### `Foam: Open Daily Note`
Simplified since it no longer has its custom settings, and re-uses all the same implementation code as `Foam: Create New Note`.
Templates can now be used with daily notes.
### Navigating to missing wikilinks
Now creates the new notes using the default template. Re-uses all the same implementation code as `Foam: Create New Note`
Now uses the contents of the wikilink as the `${title}` parameter for the template.
### `Foam: Create Note From Template`
Almost the exact same as it is today. However, with `${title}` and `filepath` templating, users will have less changes to make in the filepath confirmation step.
It's the slower but more powerful version of `Foam: Create New Note`, allowing you to pick any template, as well as customize the filepath.
## Extensions
In addition to the ideas of this proposal, there are ways we could imagine extending it. These are all "out of scope" for this design, but thinking about them could be useful to guide our thinking about this design.
### More variables in templates
`${title}` is necessary in this case to replace the functionality of `Markdown Notes: New Note`.
However, one could imagine that this pattern of "Ask the user for a value for missing variable values" could be useful in other situations too.
Perhaps users could even define their own (namespaced) template variables, and Foam would ask them for values to use for each when creating a note using a template that used those variables.
### `defaultFilepath`
By using `defaultFilepath` instead of `filepath` in the metadata section, you could have more control over the note creation without having to fall back to the full `Create New Note From Template` workflow.
* `filepath` will not ask the user for the file path, simply use the value provided (as described above)
* `defaultFilepath` will ask the user for the file path, pre-populating the file path using `defaultFilepath`
The first allows "one-click" note creation, the second more customization.
This might not be necessary, or this might not be the right way to solve the problem. We'll see.
### Arbitrary hotkey -> template mappings?
`Foam: Open Daily Note` and `Foam: Create New Note` only differ by their hotkey and their default template setting.
Is there a reason/opportunity to abstract this further and allow for users to define custom `hotkey -> template` mappings?

View File

@@ -2,20 +2,22 @@
## Using foam-gatsby-template
You can use [foam-gatsby-template](https://github.com/mathieudutour/foam-gatsby-template) to generate a static site to host it online on Github or [Vercel](https://vercel.com).
You can use [foam-gatsby-template](https://github.com/mathieudutour/foam-gatsby-template) to generate a static site to host it online on GitHub or [Vercel](https://vercel.com).
### Publishing your foam to GitHub pages
It comes configured with Github actions to auto deploy to Github pages when changes are pushed to your main branch.
It comes configured with GitHub actions to auto deploy to GitHub pages when changes are pushed to your main branch.
### Publishing your foam to Vercel
When you're ready to publish, run a local build.
```bash
cd _layouts
npm run build
```
Remove `public` from your .gitignore file then commit and push your public folder in `_layouts` to Github.
Remove `public` from your .gitignore file then commit and push your public folder in `_layouts` to GitHub.
Log into your Vercel account. (Create one if you don't have it already.)
@@ -26,3 +28,7 @@ That's it!
## Using foam-template-gatsby-kb
You can use another template [foam-template-gatsby-kb](https://github.com/hikerpig/foam-template-gatsby-kb), and host it on [Vercel](https://vercel.com) or [Netlify](https://www.netlify.com/).
## Using foam-template-gatsby-theme-primer-wiki
You can use another template [foam-template-gatsby-theme-primer-wiki](https://github.com/theowenyoung/foam-template-gatsby-theme-primer-wiki), ([Demo](https://demo-wiki.owenyoung.com/)), and host it on Github Pages, [Vercel](https://vercel.com) or [Netlify](https://www.netlify.com/).

View File

@@ -11,14 +11,15 @@ The following recipe is written with the assumption that you already have an [Az
1. Generate a Foam workspace using the [foam-template project](https://github.com/foambubble/foam-template).
2. Change the remote to a git repository in Azure DevOps (Repos -> Import a Repository -> Add Clone URL with Authentication), or copy all the files into a new Azure DevOps git repository.
3. Define which document will be the wiki home page. To do that, create a file called `.order` in the Foam workspace root folder, with first line being the document filename without `.md` extension. For a project created from the Foam template, the file would look like this:
```
readme
```
4. Push the repository to remote in Azure DevOps.
## Publish repository to a wiki
1. Navigate to your Azure DevOps project in a web browser.
2. Choose **Overview** > **Wiki**. If you don't have wikis for your project, choose **Publish code as a wiki** on welcome page.
3. Choose repository with your Foam workspace, branch (usually `master` or `main`), folder (for workspace created from foam-template it is `/`), and wiki name, and press **Publish**.
@@ -40,6 +41,7 @@ While you are pushing changes to GitHub, you won't see the wiki updated if you d
3. You can then add the remote for your second remote repository, in this case, Azure. e.g `git remote add azure https://<YOUR_ID>@dev.azure.com/<YOUR_ID>/foam-notes/_git/foam-notes`. You can get it from: Repos->Files->Clone and copy the URL.
4. Now, you need to set up your origin remote to push to both of these. So run: `git config -e` and edit it.
5. Add the `remote origin` section to the bottom of the file with the URLs from each remote repository you'd like to push to. You'll see something like that:
```bash
[core]
...
@@ -58,6 +60,7 @@ While you are pushing changes to GitHub, you won't see the wiki updated if you d
url = git@github.com:username/repo.git
url = https://<YOUR_ID>@dev.azure.com/<YOUR_ID>/foam-notes/_git/foam-notes
```
6. You can then push to both repositories by: `git push origin master` or a single one using: `git push github master` or `git push azure master`
For more information, read the [Azure DevOps documentation](https://docs.microsoft.com/en-us/azure/devops/project/wiki/publish-repo-to-wiki).

View File

@@ -1,42 +1,49 @@
# Github Pages
# GitHub Pages
- The [Foam template](https://github.com/foambubble/foam-template) is **GitHub Pages** ready, all you have to do is [turn it on in your repository settings](https://guides.github.com/features/pages/).
- In VSCode workspace settings set `"foam.edit.linkReferenceDefinitions": "withoutExtensions"`
- Execute the “Foam: Run Janitor” command from the command palette.
- [Turn **GitHub Pages** on in your repository settings](https://guides.github.com/features/pages/).
- The default GitHub Pages template is called [Primer](https://github.com/pages-themes/primer). See Primer docs for how to customise html layouts and templates.
- GitHub Pages is built on [Jekyll](https://jekyllrb.com/), so it supports things like permalinks, front matter metadata etc.
## How to publish locally
If you want to test your published foam, follow the instructions:
- https://docs.github.com/en/free-pro-team@latest/github/working-with-github-pages/creating-a-github-pages-site-with-jekyll
- https://docs.github.com/en/free-pro-team@latest/github/working-with-github-pages/testing-your-github-pages-site-locally-with-jekyll
- <https://docs.github.com/en/free-pro-team@latest/github/working-with-github-pages/creating-a-github-pages-site-with-jekyll>
- <https://docs.github.com/en/free-pro-team@latest/github/working-with-github-pages/testing-your-github-pages-site-locally-with-jekyll>
Assuming you have installed ruby/jekyll and the rest:
- `touch Gemfile`
- open the file and paste the following:
```
source 'https://rubygems.org'
gem "github-pages", "VERSION"
```
replacing `VERSION` with the latest from https://rubygems.org/gems/github-pages (e.g. `gem "github-pages", "209"`)
replacing `VERSION` with the latest from <https://rubygems.org/gems/github-pages> (e.g. `gem "github-pages", "209"`)
- `bundle`
- `bundle exec jekyll 3.9.0 new .`
- edit the `Gemfile` according to the instructions at [Creating Your Site](https://docs.github.com/en/free-pro-team@latest/github/working-with-github-pages/creating-a-github-pages-site-with-jekyll#creating-your-site) Point n.8
- `bundle exec jekyll serve`
## Other templates
There are many other templates which also support publish your foam workspace to github pages
* gatsby-digital-garden
* [repo](https://github.com/mathieudutour/gatsby-digital-garden)
* [demo-website](https://mathieudutour.github.io/gatsby-digital-garden/)
* [repo](https://github.com/mathieudutour/gatsby-digital-garden)
* [demo-website](https://mathieudutour.github.io/gatsby-digital-garden/)
* foam-mkdocs-template
* [repo](https://github.com/Jackiexiao/foam-mkdocs-template)
* [demo-website](https://jackiexiao.github.io/foam/)
* [repo](https://github.com/Jackiexiao/foam-mkdocs-template)
* [demo-website](https://jackiexiao.github.io/foam/)
* foam-jekyll-template
* [repo](https://github.com/hikerpig/foam-jekyll-template)
* [demo-website](https://hikerpig.github.io/foam-jekyll-template/)
* [repo](https://github.com/hikerpig/foam-jekyll-template)
* [demo-website](https://hikerpig.github.io/foam-jekyll-template/)
[[todo]] [[good-first-task]] Improve this documentation

View File

@@ -5,11 +5,13 @@ The standard [foam-template](https://github.com/foambubble/foam-template) is rea
## Enable navigation in GitHub
To allow navigation from within the GitHub repo, make sure to generate the link references, by setting
- `Foam Edit: Link Reference Definitions` -> `withExtensions`
See [[link-reference-definitions]] for more information.
## Customising the style
You can edit `assets/css/style.scss` to change how published pages look.
[//begin]: # "Autogenerated link references for markdown compatibility"

View File

@@ -11,6 +11,7 @@ Generate a solution using the [Foam template].
Change the remote to GitLab, or copy all the files into a new GitLab repo.
### Add a _config.yaml
Add another file to the root directory (the one with `readme.md` in it) called `_config.yaml` (no extension)
```yaml

View File

@@ -3,6 +3,7 @@
You can use [foam-eleventy-template](https://github.com/juanfrank77/foam-eleventy-template) to generate a static site with [Eleventy](https://www.11ty.dev/), and host it online on [Netlify](https://www.netlify.com/).
With this template you can
- Have control over what to publish and what to keep private
- Customize the styling of the site to your own liking
@@ -12,8 +13,6 @@ When you're ready to publish, import the GitHub repository you created with **fo
Once that's done, all you have to do is make changes to your workspace in VS Code and push them to the main branch on GitHub. Netlify will recognize the changes, deploy them automatically and give you a link where your Foam is published.
That's it!
You can now see it online and use that link to share it with your friends, so that they can see it too.

View File

@@ -82,6 +82,6 @@ Finally, if all is successful, Vercel will show the detected framework: Jekyll.
And now, Vercel will take care of building and rendering our foam workspace each time on push. Vercel will publish our site to `xxx.vercel.app`, we can also define a custom domain name for our Vercel website.
[//begin]: # "Autogenerated link references for markdown compatibility"
[publish-to-github-pages]: publish-to-github-pages.md "Github Pages"
[publish-to-github-pages]: publish-to-github-pages.md "GitHub Pages"
[math-support-with-katex]: math-support-with-katex.md "Katex Math Rendering"
[//end]: # "Autogenerated link references"

View File

@@ -5,8 +5,6 @@
- [VSCode Extensions Packs](https://code.visualstudio.com/blogs/2017/03/07/extension-pack-roundup) [[todo]] Evaluate for deployment
- [Dark mode](https://css-tricks.com/dark-modes-with-css/)
[//begin]: # "Autogenerated link references for markdown compatibility"
[todo]: dev/todo.md "Todo"
[//end]: # "Autogenerated link references"

View File

@@ -5,7 +5,7 @@ You can also easily manipulate the git history to reduce clutter.
## Required Extensions
- [GitDoc](https://marketplace.visualstudio.com/items?itemName=vsls-contrib.gitdoc)
- [GitDoc](https://marketplace.visualstudio.com/items?itemName=vsls-contrib.gitdoc)
## Instructions
@@ -18,9 +18,6 @@ __For Foam specific needs, you can add a comment here by following the [[contrib
- Feedback and issues with the extension should be reported to the authors themselves
- Feedback and issues with the integration of the extension in Foam can be reported in our [issue tracker](https://github.com/foambubble/foam/issues)
[//begin]: # "Autogenerated link references for markdown compatibility"
[contribution-guide]: ../contribution-guide.md "Contribution Guide"
[//end]: # "Autogenerated link references"

View File

@@ -4,7 +4,7 @@ With this #recipe you can convert a link to a fully-formed Markdown link, using
## Required Extensions
- [Markdown Link Expander](https://marketplace.visualstudio.com/items?itemName=skn0tt.markdown-link-expander) (not included in template)
- [Markdown Link Expander](https://marketplace.visualstudio.com/items?itemName=skn0tt.markdown-link-expander) (not included in template)
Markdown Link Expander will scrape your URL's `<title>` tag to create a nice Markdown-style link.
@@ -22,4 +22,3 @@ Tip: If you paste a lot of links, give the action a custom [key binding](https:/
## Feedback and issues
Have an idea for the extension? [Feel free to share! 🎉](https://github.com/Skn0tt/markdown-link-expander/issues)

View File

@@ -30,7 +30,7 @@ With this #recipe you can create notes on your iOS device, which will automatica
2. the repository name of your Foam repo
3. the GitHub access token from step 7
4. An author name
11. Check your Github repo for a commit
11. Check your GitHub repo for a commit
12. If you are publishing your Foam to the web you may want to edit your publishing configuration to exclude inbox files - as publishing (and method) is a user choice that is beyond the scope of this recipe
## Code for Drafts Action

View File

@@ -15,8 +15,7 @@ With this #recipe you can create notes on your iOS device, which will automatica
## Instructions
1. Setup the [`foam-capture-action`]() in your GitHub Repository, to be triggered by "Workflow dispatch" events.
1. Setup the [`foam-capture-action`]() in your GitHub Repository, to be triggered by "Workflow dispatch" events.
```
name: Manually triggered workflow
@@ -26,15 +25,17 @@ on:
data:
description: 'What information to put in the knowledge base.'
required: true
jobs:
store_data:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: anglinb/foam-capture-action@main
with:
with:
{% raw %}
capture: ${{ github.event.inputs.data }}
{% endraw %}
- run: |
git config --local user.email "example@gmail.com"
git config --local user.name "Your name"
@@ -44,14 +45,16 @@ jobs:
2. In GitHub [create a Personal Access Token](https://github.com/settings/tokens) and give it `repo` scope - make a note of the token
3. Run this command to find your `workflow-id` to be used in the Shortcut.
```bash
curl \
-H "Accept: application/vnd.github.v3+json" \
-H "Authorization: Bearer <GITHUB_TOKEN>" \
https://api.github.com/repos/<owner>/<repository>/actions/workflows
```
4. Copy this [Shortcut](https://www.icloud.com/shortcuts/57d2ed90c40e43a5badcc174ebfaaf1d) to your iOS devices and edit the contents of the last step, `GetContentsOfURL`
- Make sure you update the URL of the shortcut step with the `owner`, `repository`, `workflow-id` (from the previous step)
- Make sure you update the headers of the shortcut step, replaceing `[GITHUB_TOKEN]` with your Personal Access Token (from step 2)
- Make sure you update the headers of the shortcut step, replaceing `[GITHUB_TOKEN]` with your Personal Access Token (from step 2)
5. Run the shortcut & celebrate! ✨ (You should see a GitHub Action run start and the text you entered show up in `inbox.md` in your repository.)

View File

@@ -7,7 +7,6 @@ We have two alternative #recipe for displaying diagrams in markdown:
- [Draw.io](#drawio)
- [Using Draw.io](#using-drawio)
## Mermaid
You can use [Mermaid](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid) plugin to draw and preview diagrams in your content.
@@ -27,7 +26,6 @@ You can use [Mermaid](https://marketplace.visualstudio.com/items?itemName=bierne
3. Start drawing your diagram. Once you done, save it.
4. Embed the diagram file as you embedding the image file, for example: `![My Diagram](my-diagram.drawio.svg)`
[//begin]: # "Autogenerated link references for markdown compatibility"
[publish-to-github-pages]: ../publishing/publish-to-github-pages.md "Github Pages"
[publish-to-github-pages]: ../publishing/publish-to-github-pages.md "GitHub Pages"
[//end]: # "Autogenerated link references"

View File

@@ -3,6 +3,7 @@
This is an example of how to structure a Recipe. The first paragraph or two should explain the purpose of the recipe succinctly, including why it's useful, if that's not obvious.
Recipes are intended to document:
- How to use Foam's basic features
- Power user pro-tips
- Useful customisations of the default Foam environment
@@ -10,8 +11,8 @@ Recipes are intended to document:
## Required Extensions
- **[Hacker Typer](https://marketplace.visualstudio.com/items?itemName=jevakallio.vscode-hacker-typer)** (not really required for this recipe, just an example)
- [Foam for VSCode](https://marketplace.visualstudio.com/items?itemName=foam.foam-vscode) (installed by default)
- **[Hacker Typer](https://marketplace.visualstudio.com/items?itemName=jevakallio.vscode-hacker-typer)** (not really required for this recipe, just an example)
- [Foam for VSCode](https://marketplace.visualstudio.com/items?itemName=foam.foam-vscode) (installed by default)
The first section should be a bulleted list of extensions required to use this recipe. At a minimum, this section should list all additional, non-standard extensions.

View File

@@ -16,11 +16,6 @@ In the future we'll want to improve this feature by
- Make back links editable using [VS Code Search Editors](https://code.visualstudio.com/updates/v1_43#_search-editors)
- [Suggested by @Jash on Discord](https://discordapp.com/channels/729975036148056075/729978910363746315/730999992419876956)
[//begin]: # "Autogenerated link references for markdown compatibility"
[materialized-backlinks]: ../dev/materialized-backlinks.md "Materialized Backlinks (stub)"
[//end]: # "Autogenerated link references"

View File

@@ -4,7 +4,6 @@
If you're interested in working on it, please start a conversation in [GitHub issues](https://github.com/foambubble/foam/issues).
[//begin]: # "Autogenerated link references for markdown compatibility"
[todo]: ../dev/todo.md "Todo"
[roadmap]: ../dev/roadmap.md "Roadmap"

View File

@@ -56,6 +56,3 @@ in `keybindings.json` (Code|File > Preferences > Keyboard Shortcuts) add binding
If you have any issues or questions please look at the [README.md](https://github.com/kneely/note-macros#note-macros) on the [note-macros](https://github.com/kneely/note-macros) GitHub.
If you run into any issues that are not fixed by referring to the README or feature requests please open an [issue](https://github.com/kneely/note-macros/issues).

View File

@@ -1,4 +1,3 @@
# Real-time Collaboration
This #recipe is here to just tell you that VS Code Live Share will allow you to collaborate live on your notes.

View File

@@ -26,15 +26,18 @@ A #recipe is a guide, tip or strategy for getting the most out of your Foam work
- Clip webpages with [[web-clipper]]
## Discover
- Explore your notes using [[graph-visualisation]]
- Discover relationships with [[backlinking]]
- Simulating [[unlinked-references]]
## Organise
- Using [[backlinking]] for reference lists.
## Write
- Link documents with [[wiki-links]].
- Link documents with [[wikilinks]].
- Use shortcuts for [[creating-new-notes]]
- Instantly create and access your [[daily-notes]]
- Add and explore [[tags]]
@@ -53,6 +56,7 @@ A #recipe is a guide, tip or strategy for getting the most out of your Foam work
- _More..._
- VS Code Advanced Features [[todo]] [[good-first-task]]
- Focus with Zen Mode
- Display content of other notes in the preview tab by [[including-notes]]
## Version control
@@ -109,7 +113,7 @@ _See [[contribution-guide]] and [[how-to-write-recipes]]._
[graph-visualisation]: ../features/graph-visualisation.md "Graph Visualisation"
[backlinking]: ../features/backlinking.md "Backlinking"
[unlinked-references]: ../dev/unlinked-references.md "Unlinked references (stub)"
[wiki-links]: ../wiki-links.md "Wiki Links"
[wikilinks]: ../wikilinks.md "Wikilinks"
[creating-new-notes]: ../features/creating-new-notes.md "Creating New Notes"
[daily-notes]: ../features/daily-notes.md "Daily notes"
[tags]: ../features/tags.md "Tags"
@@ -122,9 +126,10 @@ _See [[contribution-guide]] and [[how-to-write-recipes]]._
[add-images-to-notes]: add-images-to-notes.md "Add images to your notes"
[shows-image-preview-on-hover]: shows-image-preview-on-hover.md "Shows Image Preview on Hover"
[good-first-task]: ../dev/good-first-task.md "Good First Task"
[including-notes]: ../features/including-notes.md "Including notes in a note"
[git-integration]: ../features/git-integration.md "Git Integration"
[write-your-notes-in-github-gist]: write-your-notes-in-github-gist.md "Write your notes in GitHub Gist"
[publish-to-github-pages]: ../publishing/publish-to-github-pages.md "Github Pages"
[publish-to-github-pages]: ../publishing/publish-to-github-pages.md "GitHub Pages"
[publish-to-gitlab-pages]: ../publishing/publish-to-gitlab-pages.md "GitLab Pages"
[publish-to-azure-devops-wiki]: ../publishing/publish-to-azure-devops-wiki.md "Publish to Azure DevOps Wiki"
[publish-to-vercel]: ../publishing/publish-to-vercel.md "Publish to Vercel"

View File

@@ -9,16 +9,18 @@ The most promising options are:
### [GitJournal](https://gitjournal.io/)
Pros
- Open source
- Already a usable solution.
- Provides functionality to edit, create, and browser markdown files.
- Support journal mode, todo lists, and free writing
- Syncs to GitHub repo
- Supports Wiki Links
- Supports Wikilinks
- Supports Backlinks
- Developer is happy to prioritize Foam compatibility
Cons
- Doesn't generate link reference lists (but this is ok, since [[workspace-janitor]] as a GitHub action can solve this)
- Not as sleek as Apple/Google notes, some keyboard state glitching on Android, etc.
- Lack of control over roadmap. Established product with a paid plan, so may not be open to Foam-supportive changes and additions that don't benefit most users.
@@ -28,13 +30,15 @@ Verdict: Good. By far best effort/outcome ratio would be to help improve GitJour
### GitHub Codespaces
Pros
- Works out of the box just like the desktop app
Cons
- not generally available quite yet
- [Pricing](https://docs.github.com/en/free-pro-team@latest/github/developing-online-with-codespaces/about-billing-for-codespaces)
For a quick demo, see https://www.youtube.com/watch?v=KI5m4Uy8_4I.
For a quick demo, see <https://www.youtube.com/watch?v=KI5m4Uy8_4I>.
Verdict: Good. Pricing should be reasonable for taking notes on the fly. Harder to assess for people who would constantly use Foam from mobile phone.
@@ -54,7 +58,6 @@ If such an app was worth building, it would have to have the following features:
Given the effort vs reward ratio, it's a low priority for core team, but if someone wants to work on this, we can provide support! Talk to us on the #mobile-apps channel on [Foam Discord](https://foambubble.github.io/join-discord/w).
[//begin]: # "Autogenerated link references for markdown compatibility"
[build-vs-assemble]: ../dev/build-vs-assemble.md "Build vs Assemble"
[workspace-janitor]: ../features/workspace-janitor.md "Janitor"

View File

@@ -34,7 +34,7 @@ Once you've opened/created the Foam repository, it will appear in the `Repositor
## Editing your workspace
When you create or open a page, you can edit the markdown content as usual, as well as [paste images](https://github.com/vsls-contrib/gistpad#pasting-images-1), and create [`[[links]]` to other pages](https://github.com/vsls-contrib/gistpad#links). When you type `[[`, you'll recieve auto-completion for the existing pages in your workspace, and you can also automatically create new pages by simply creating a link to it.
When you create or open a page, you can edit the markdown content as usual, as well as [paste images](https://github.com/vsls-contrib/gistpad#pasting-images-1), and create [`[[links]]` to other pages](https://github.com/vsls-contrib/gistpad#links). When you type `[[`, you'll receive auto-completion for the existing pages in your workspace, and you can also automatically create new pages by simply creating a link to it.
Since you're using the Visual Studio Code markdown editor, you can benefit from all of the rich language services (e.g. syntax highlighting, header collapsing), as well as the extension ecosystem (e.g. [Emojisense](https://marketplace.visualstudio.com/items?itemName=bierner.emojisense)).

View File

@@ -5,10 +5,9 @@ These extensions defined in `.vscode/extensions.json` are automatically installe
This list is subject to change. Especially the Git ones.
- [Foam for VSCode](https://marketplace.visualstudio.com/items?itemName=foam.foam-vscode) (alpha)
- [Markdown Notes](https://marketplace.visualstudio.com/items?itemName=kortina.vscode-markdown-notes)
- [Markdown Links](https://marketplace.visualstudio.com/items?itemName=tchayen.markdown-links)
- [Markdown All In One](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one)
- [Paste Image](https://marketplace.visualstudio.com/items?itemName=mushan.vscode-paste-image)
- [Spell Right](https://marketplace.visualstudio.com/items?itemName=ban.spellright)
## Extensions For Additional Features
@@ -16,10 +15,11 @@ These extensions are not (yet?) defined in `.vscode/extensions.json`, but have b
- [Emojisense](https://marketplace.visualstudio.com/items?itemName=bierner.emojisense)
- [Markdown Emoji](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-emoji) (adds `:smile:` syntax, works with emojisense to provide autocomplete for this syntax)
- [Mermaid Support for Preview](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid)
- [Markdown Preview Mermaid Support](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid)
- [Mermaid Markdown Syntax Highlighting](https://marketplace.visualstudio.com/items?itemName=bpruitt-goddard.mermaid-markdown-syntax-highlighting)
- [VSCode PDF Viewing](https://marketplace.visualstudio.com/items?itemName=tomoki1207.pdf)
- [Git Lens](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens)
- [Markdown Extended](https://marketplace.visualstudio.com/items?itemName=jebbs.markdown-extended) (with `kbd` option disabled, `kbd` turns wiki-links into non-clickable buttons)
- [Project Manager](https://marketplace.visualstudio.com/items?itemName=alefragnani.project-manager) (to quickly switch between projects)
- [Markdown Extended](https://marketplace.visualstudio.com/items?itemName=jebbs.markdown-extended) (with `kbd` option disabled, `kbd` turns wikilinks into non-clickable buttons)
- [GitDoc](https://marketplace.visualstudio.com/items?itemName=vsls-contrib.gitdoc) (easy version management via git auto commits)
- [Markdown Footnotes](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-footnotes) (Adds [^footnote] syntax support to VS Code's built-in markdown preview)
- [Todo Tree](https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.todo-tree) (Searches workspace for TODO and related comments and summarizes those lines in vs-code gutter)

View File

@@ -17,4 +17,3 @@ Also happens to sound quite a lot like Home. Funny, that.
## Bubble
Individual Foam note, written in Markdown.

View File

@@ -1,27 +1,29 @@
# Wiki Links
# Wikilinks
Foam enables you to Link pages together using `[[file-name]]` annotations (i.e. `[[media-wiki]]` links).
Foam enables you to Link pages together using `[[file-name]]` annotations (i.e. `[[MediaWiki]]` links).
- Type `[[` and start typing a file name for autocompletion.
- Note that your file names should be in `lower-dash-case.md`, and your wiki links should reference file names exactly: `[[lower-dash-case]]`, not `[[Lower Dash Case]]`.
- See [[link-formatting-and-autocompletion]] for more information, and how to setup your link autocompletions to make this easier.
- `Cmd` + `Click` ( `Ctrl` + `Click` on Windows ) on file name to navigate to file (`F12` also works while your cursor is on the file name)
- `Cmd` + `Click` ( `Ctrl` + `Click` on Windows ) on non-existent file to create that file in the workspace.
- The note creation makes use of the special [`new-note.md` note template](features/note-templates)
> If the `F12` shortcut feels unnatural you can rebind it at File > Preferences > Keyboard Shortcuts by searching for `editor.action.revealDefinition`.
## Markdown compatibility
The [Foam for VSCode](https://marketplace.visualstudio.com/items?itemName=foam.foam-vscode) extension automatically generates [[link-reference-definitions]] at the bottom of the file to make wiki-links compatible with Markdown tools and parsers.
The [Foam for VSCode](https://marketplace.visualstudio.com/items?itemName=foam.foam-vscode) extension automatically generates [[link-reference-definitions]] at the bottom of the file to make wikilinks compatible with Markdown tools and parsers.
## Read more
- [[foam-file-format]]
- [[note-templates]]
- [[link-formatting-and-autocompletion]]
- See [[link-reference-definition-improvements]] for further discussion on current problems and potential solutions.
[//begin]: # "Autogenerated link references for markdown compatibility"
[link-reference-definitions]: features/link-reference-definitions.md "Link Reference Definitions"
[foam-file-format]: dev/foam-file-format.md "Foam File Format"
[note-templates]: features/note-templates.md "Note Templates"
[link-reference-definition-improvements]: dev/link-reference-definition-improvements.md "Link Reference Definition Improvements"
[//end]: # "Autogenerated link references"

View File

@@ -4,5 +4,5 @@
],
"npmClient": "yarn",
"useWorkspaces": true,
"version": "0.12.0"
"version": "0.15.4"
}

View File

@@ -9,10 +9,6 @@
"packages/*"
],
"scripts": {
"start:vscode": "yarn workspace foam-vscode vscode:start-debugging",
"build:core": "yarn workspace foam-core build",
"watch:core": "yarn workspace foam-core start",
"test:core": "yarn workspace foam-core test",
"vscode:package-extension": "yarn workspace foam-vscode package-extension",
"vscode:install-extension": "yarn workspace foam-vscode install-extension",
"vscode:publish-extension": "yarn workspace foam-vscode publish-extension",
@@ -40,5 +36,6 @@
"semi": true,
"singleQuote": true,
"trailingComma": "es5"
}
},
"dependencies": {}
}

View File

@@ -1,3 +0,0 @@
module.exports = {
plugins: [['@babel/plugin-transform-runtime', { helpers: false }]],
};

View File

@@ -1,21 +0,0 @@
# Foam Core
This module contains the core functions, model, and API of Foam.
It is used by its clients to integrate Foam in various use cases, from VsCode extension, to CLI, to CI integrations.
## Local Development
Below is a list of commands you will probably find useful.
### `yarn watch`
Runs the project in development/watch mode. Your project will be rebuilt upon changes.
### `yarn build`
Bundles the package to the `dist` folder. The package is optimized and bundled with Rollup into multiple formats (CommonJS, UMD, and ES Module).
### `yarn test`
Runs the test watcher (Jest) in an interactive mode.
By default, runs tests related to files changed since the last commit.

View File

@@ -1,48 +0,0 @@
{
"name": "foam-core",
"repository": "https://github.com/foambubble/foam",
"version": "0.12.0",
"license": "MIT",
"files": [
"dist"
],
"scripts": {
"clean": "rimraf dist",
"build": "tsdx build --tsconfig ./tsconfig.build.json",
"test": "tsdx test",
"lint": "tsdx lint src test",
"watch": "tsdx watch",
"prepare": "tsdx build --tsconfig ./tsconfig.build.json"
},
"devDependencies": {
"@babel/core": "^7.10.4",
"@babel/plugin-transform-runtime": "^7.10.4",
"@babel/preset-env": "^7.10.4",
"@babel/preset-typescript": "^7.10.4",
"@types/github-slugger": "^1.3.0",
"@types/lodash": "^4.14.157",
"@types/micromatch": "^4.0.1",
"@types/picomatch": "^2.2.1",
"husky": "^4.2.5",
"tsdx": "^0.13.2",
"tslib": "^2.0.0",
"typescript": "^3.9.5"
},
"dependencies": {
"detect-newline": "^3.1.0",
"fast-array-diff": "^1.0.0",
"github-slugger": "^1.3.0",
"glob": "^7.1.6",
"lodash": "^4.17.19",
"micromatch": "^4.0.2",
"remark-frontmatter": "^2.0.0",
"remark-parse": "^8.0.2",
"remark-wiki-link": "^0.0.4",
"title-case": "^3.0.2",
"unified": "^9.0.0",
"unist-util-visit": "^2.0.2",
"yaml": "^1.10.0"
},
"main": "dist/index.js",
"types": "dist/index.d.ts"
}

View File

@@ -1,56 +0,0 @@
import { createMarkdownParser } from './markdown-provider';
import { FoamConfig, Foam, IDataStore } from './index';
import { loadPlugins } from './plugins';
import { isSome } from './utils';
import { Logger } from './utils/log';
import { isMarkdownFile } from './utils/uri';
import { FoamWorkspace } from './model/workspace';
export const bootstrap = async (config: FoamConfig, dataStore: IDataStore) => {
const plugins = await loadPlugins(config);
const parserPlugins = plugins.map(p => p.parser).filter(isSome);
const parser = createMarkdownParser(parserPlugins);
const workspace = new FoamWorkspace();
const files = await dataStore.listFiles();
await Promise.all(
files.map(async uri => {
Logger.info('Found: ' + uri);
if (isMarkdownFile(uri)) {
const content = await dataStore.read(uri);
if (isSome(content)) {
workspace.set(parser.parse(uri, content));
}
}
})
);
workspace.resolveLinks(true);
const listeners = [
dataStore.onDidChange(async uri => {
const content = await dataStore.read(uri);
workspace.set(await parser.parse(uri, content));
}),
dataStore.onDidCreate(async uri => {
const content = await dataStore.read(uri);
workspace.set(await parser.parse(uri, content));
}),
dataStore.onDidDelete(uri => {
workspace.delete(uri);
}),
];
return {
workspace: workspace,
config: config,
services: {
dataStore,
parser,
},
dispose: () => {
listeners.forEach(l => l.dispose());
workspace.dispose();
},
} as Foam;
};

View File

@@ -1,748 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// taken from https://github.com/microsoft/vscode/tree/master/src/vs/base/common
import { isWindows } from './platform';
import { CharCode } from './charCode';
import * as paths from 'path';
const _schemePattern = /^\w[\w\d+.-]*$/;
const _singleSlashStart = /^\//;
const _doubleSlashStart = /^\/\//;
function _validateUri(ret: URI, _strict?: boolean): void {
// scheme, must be set
if (!ret.scheme && _strict) {
throw new Error(
`[UriError]: Scheme is missing: {scheme: "", authority: "${ret.authority}", path: "${ret.path}", query: "${ret.query}", fragment: "${ret.fragment}"}`
);
}
// scheme, https://tools.ietf.org/html/rfc3986#section-3.1
// ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
if (ret.scheme && !_schemePattern.test(ret.scheme)) {
throw new Error('[UriError]: Scheme contains illegal characters.');
}
// path, http://tools.ietf.org/html/rfc3986#section-3.3
// If a URI contains an authority component, then the path component
// must either be empty or begin with a slash ("/") character. If a URI
// does not contain an authority component, then the path cannot begin
// with two slash characters ("//").
if (ret.path) {
if (ret.authority) {
if (!_singleSlashStart.test(ret.path)) {
throw new Error(
'[UriError]: If a URI contains an authority component, then the path component must either be empty or begin with a slash ("/") character'
);
}
} else {
if (_doubleSlashStart.test(ret.path)) {
throw new Error(
'[UriError]: If a URI does not contain an authority component, then the path cannot begin with two slash characters ("//")'
);
}
}
}
}
// for a while we allowed uris *without* schemes and this is the migration
// for them, e.g. an uri without scheme and without strict-mode warns and falls
// back to the file-scheme. that should cause the least carnage and still be a
// clear warning
function _schemeFix(scheme: string, _strict: boolean): string {
if (!scheme && !_strict) {
return 'file';
}
return scheme;
}
// implements a bit of https://tools.ietf.org/html/rfc3986#section-5
function _referenceResolution(scheme: string, path: string): string {
// the slash-character is our 'default base' as we don't
// support constructing URIs relative to other URIs. This
// also means that we alter and potentially break paths.
// see https://tools.ietf.org/html/rfc3986#section-5.1.4
switch (scheme) {
case 'https':
case 'http':
case 'file':
if (!path) {
path = _slash;
} else if (path[0] !== _slash) {
path = _slash + path;
}
break;
}
return path;
}
const _empty = '';
const _slash = '/';
const _regexp = /^(([^:/?#]+?):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;
/**
* Uniform Resource Identifier (URI) http://tools.ietf.org/html/rfc3986.
* This class is a simple parser which creates the basic component parts
* (http://tools.ietf.org/html/rfc3986#section-3) with minimal validation
* and encoding.
*
* ```txt
* foo://example.com:8042/over/there?name=ferret#nose
* \_/ \______________/\_________/ \_________/ \__/
* | | | | |
* scheme authority path query fragment
* | _____________________|__
* / \ / \
* urn:example:animal:ferret:nose
* ```
*/
export class URI implements UriComponents {
static isUri(thing: any): thing is URI {
if (thing instanceof URI) {
return true;
}
if (!thing) {
return false;
}
return (
typeof (thing as URI).authority === 'string' &&
typeof (thing as URI).fragment === 'string' &&
typeof (thing as URI).path === 'string' &&
typeof (thing as URI).query === 'string' &&
typeof (thing as URI).scheme === 'string'
// typeof (thing as URI).fsPath === 'function' &&
// typeof (thing as URI).with === 'function' &&
// typeof (thing as URI).toString === 'function'
);
}
/**
* scheme is the 'http' part of 'http://www.msft.com/some/path?query#fragment'.
* The part before the first colon.
*/
readonly scheme: string;
/**
* authority is the 'www.msft.com' part of 'http://www.msft.com/some/path?query#fragment'.
* The part between the first double slashes and the next slash.
*/
readonly authority: string;
/**
* path is the '/some/path' part of 'http://www.msft.com/some/path?query#fragment'.
*/
readonly path: string;
/**
* query is the 'query' part of 'http://www.msft.com/some/path?query#fragment'.
*/
readonly query: string;
/**
* fragment is the 'fragment' part of 'http://www.msft.com/some/path?query#fragment'.
*/
readonly fragment: string;
/**
* @internal
*/
protected constructor(
scheme: string,
authority?: string,
path?: string,
query?: string,
fragment?: string,
_strict?: boolean
);
/**
* @internal
*/
protected constructor(components: UriComponents);
/**
* @internal
*/
protected constructor(
schemeOrData: string | UriComponents,
authority?: string,
path?: string,
query?: string,
fragment?: string,
_strict: boolean = false
) {
if (typeof schemeOrData === 'object') {
this.scheme = schemeOrData.scheme || _empty;
this.authority = schemeOrData.authority || _empty;
this.path = schemeOrData.path || _empty;
this.query = schemeOrData.query || _empty;
this.fragment = schemeOrData.fragment || _empty;
// no validation because it's this URI
// that creates uri components.
// _validateUri(this);
} else {
this.scheme = _schemeFix(schemeOrData, _strict);
this.authority = authority || _empty;
this.path = _referenceResolution(this.scheme, path || _empty);
this.query = query || _empty;
this.fragment = fragment || _empty;
_validateUri(this, _strict);
}
}
// ---- filesystem path -----------------------
/**
* Returns a string representing the corresponding file system path of this URI.
* Will handle UNC paths, normalizes windows drive letters to lower-case, and uses the
* platform specific path separator.
*
* * Will *not* validate the path for invalid characters and semantics.
* * Will *not* look at the scheme of this URI.
* * The result shall *not* be used for display purposes but for accessing a file on disk.
*
*
* The *difference* to `URI#path` is the use of the platform specific separator and the handling
* of UNC paths. See the below sample of a file-uri with an authority (UNC path).
*
* ```ts
const u = URI.parse('file://server/c$/folder/file.txt')
u.authority === 'server'
u.path === '/shares/c$/file.txt'
u.fsPath === '\\server\c$\folder\file.txt'
```
*
* Using `URI#path` to read a file (using fs-apis) would not be enough because parts of the path,
* namely the server name, would be missing. Therefore `URI#fsPath` exists - it's sugar to ease working
* with URIs that represent files on disk (`file` scheme).
*/
get fsPath(): string {
// if (this.scheme !== 'file') {
// console.warn(`[UriError] calling fsPath with scheme ${this.scheme}`);
// }
return uriToFsPath(this, false);
}
// ---- modify to new -------------------------
with(change: {
scheme?: string;
authority?: string | null;
path?: string | null;
query?: string | null;
fragment?: string | null;
}): URI {
if (!change) {
return this;
}
let { scheme, authority, path, query, fragment } = change;
if (scheme === undefined) {
scheme = this.scheme;
} else if (scheme === null) {
scheme = _empty;
}
if (authority === undefined) {
authority = this.authority;
} else if (authority === null) {
authority = _empty;
}
if (path === undefined) {
path = this.path;
} else if (path === null) {
path = _empty;
}
if (query === undefined) {
query = this.query;
} else if (query === null) {
query = _empty;
}
if (fragment === undefined) {
fragment = this.fragment;
} else if (fragment === null) {
fragment = _empty;
}
if (
scheme === this.scheme &&
authority === this.authority &&
path === this.path &&
query === this.query &&
fragment === this.fragment
) {
return this;
}
return new Uri(scheme, authority, path, query, fragment);
}
// ---- parse & validate ------------------------
/**
* Creates a new URI from a string, e.g. `http://www.msft.com/some/path`,
* `file:///usr/home`, or `scheme:with/path`.
*
* @param value A string which represents an URI (see `URI#toString`).
*/
static parse(value: string, _strict: boolean = false): URI {
const match = _regexp.exec(value);
if (!match) {
return new Uri(_empty, _empty, _empty, _empty, _empty);
}
return new Uri(
match[2] || _empty,
percentDecode(match[4] || _empty),
percentDecode(match[5] || _empty),
percentDecode(match[7] || _empty),
percentDecode(match[9] || _empty),
_strict
);
}
/**
* Creates a new URI from a file system path, e.g. `c:\my\files`,
* `/usr/home`, or `\\server\share\some\path`.
*
* The *difference* between `URI#parse` and `URI#file` is that the latter treats the argument
* as path, not as stringified-uri. E.g. `URI.file(path)` is **not the same as**
* `URI.parse('file://' + path)` because the path might contain characters that are
* interpreted (# and ?). See the following sample:
* ```ts
const good = URI.file('/coding/c#/project1');
good.scheme === 'file';
good.path === '/coding/c#/project1';
good.fragment === '';
const bad = URI.parse('file://' + '/coding/c#/project1');
bad.scheme === 'file';
bad.path === '/coding/c'; // path is now broken
bad.fragment === '/project1';
```
*
* @param path A file system path (see `URI#fsPath`)
*/
static file(path: string): URI {
let authority = _empty;
// normalize to fwd-slashes on windows,
// on other systems bwd-slashes are valid
// filename character, eg /f\oo/ba\r.txt
if (isWindows) {
path = path.replace(/\\/g, _slash);
}
// check for authority as used in UNC shares
// or use the path as given
if (path[0] === _slash && path[1] === _slash) {
const idx = path.indexOf(_slash, 2);
if (idx === -1) {
authority = path.substring(2);
path = _slash;
} else {
authority = path.substring(2, idx);
path = path.substring(idx) || _slash;
}
}
return new Uri('file', authority, path, _empty, _empty);
}
static from(components: {
scheme: string;
authority?: string;
path?: string;
query?: string;
fragment?: string;
}): URI {
return new Uri(
components.scheme,
components.authority,
components.path,
components.query,
components.fragment
);
}
/**
* Join a URI path with path fragments and normalizes the resulting path.
*
* @param uri The input URI.
* @param pathFragment The path fragment to add to the URI path.
* @returns The resulting URI.
*/
static joinPath(uri: URI, ...pathFragment: string[]): URI {
if (!uri.path) {
throw new Error(`[UriError]: cannot call joinPath on URI without path`);
}
let newPath: string;
if (isWindows && uri.scheme === 'file') {
newPath = URI.file(
paths.win32.join(uriToFsPath(uri, true), ...pathFragment)
).path;
} else {
newPath = paths.posix.join(uri.path, ...pathFragment);
}
return uri.with({ path: newPath });
}
// ---- printing/externalize ---------------------------
/**
* Creates a string representation for this URI. It's guaranteed that calling
* `URI.parse` with the result of this function creates an URI which is equal
* to this URI.
*
* * The result shall *not* be used for display purposes but for externalization or transport.
* * The result will be encoded using the percentage encoding and encoding happens mostly
* ignore the scheme-specific encoding rules.
*
* @param skipEncoding Do not encode the result, default is `false`
*/
toString(skipEncoding: boolean = false): string {
return _asFormatted(this, skipEncoding);
}
toJSON(): UriComponents {
return this;
}
static revive(data: UriComponents | URI): URI;
static revive(data: UriComponents | URI | undefined): URI | undefined;
static revive(data: UriComponents | URI | null): URI | null;
static revive(
data: UriComponents | URI | undefined | null
): URI | undefined | null;
static revive(
data: UriComponents | URI | undefined | null
): URI | undefined | null {
if (!data) {
return data;
} else if (data instanceof URI) {
return data;
} else {
const result = new Uri(data);
result._formatted = (data as UriState).external;
result._fsPath =
(data as UriState)._sep === _pathSepMarker
? (data as UriState).fsPath
: null;
return result;
}
}
}
export interface UriComponents {
scheme: string;
authority: string;
path: string;
query: string;
fragment: string;
}
interface UriState extends UriComponents {
$mid: number;
external: string;
fsPath: string;
_sep: 1 | undefined;
}
const _pathSepMarker = isWindows ? 1 : undefined;
// This class exists so that URI is compatible with vscode.Uri (API).
class Uri extends URI {
_formatted: string | null = null;
_fsPath: string | null = null;
get fsPath(): string {
if (!this._fsPath) {
this._fsPath = uriToFsPath(this, false);
}
return this._fsPath;
}
toString(skipEncoding: boolean = false): string {
if (!skipEncoding) {
if (!this._formatted) {
this._formatted = _asFormatted(this, false);
}
return this._formatted;
} else {
// we don't cache that
return _asFormatted(this, true);
}
}
toJSON(): UriComponents {
const res = {
$mid: 1,
} as UriState;
// cached state
if (this._fsPath) {
res.fsPath = this._fsPath;
res._sep = _pathSepMarker;
}
if (this._formatted) {
res.external = this._formatted;
}
// uri components
if (this.path) {
res.path = this.path;
}
if (this.scheme) {
res.scheme = this.scheme;
}
if (this.authority) {
res.authority = this.authority;
}
if (this.query) {
res.query = this.query;
}
if (this.fragment) {
res.fragment = this.fragment;
}
return res;
}
}
// reserved characters: https://tools.ietf.org/html/rfc3986#section-2.2
const encodeTable: { [ch: number]: string } = {
[CharCode.Colon]: '%3A', // gen-delims
[CharCode.Slash]: '%2F',
[CharCode.QuestionMark]: '%3F',
[CharCode.Hash]: '%23',
[CharCode.OpenSquareBracket]: '%5B',
[CharCode.CloseSquareBracket]: '%5D',
[CharCode.AtSign]: '%40',
[CharCode.ExclamationMark]: '%21', // sub-delims
[CharCode.DollarSign]: '%24',
[CharCode.Ampersand]: '%26',
[CharCode.SingleQuote]: '%27',
[CharCode.OpenParen]: '%28',
[CharCode.CloseParen]: '%29',
[CharCode.Asterisk]: '%2A',
[CharCode.Plus]: '%2B',
[CharCode.Comma]: '%2C',
[CharCode.Semicolon]: '%3B',
[CharCode.Equals]: '%3D',
[CharCode.Space]: '%20',
};
function encodeURIComponentFast(
uriComponent: string,
allowSlash: boolean
): string {
let res: string | undefined = undefined;
let nativeEncodePos = -1;
for (let pos = 0; pos < uriComponent.length; pos++) {
const code = uriComponent.charCodeAt(pos);
// unreserved characters: https://tools.ietf.org/html/rfc3986#section-2.3
if (
(code >= CharCode.a && code <= CharCode.z) ||
(code >= CharCode.A && code <= CharCode.Z) ||
(code >= CharCode.Digit0 && code <= CharCode.Digit9) ||
code === CharCode.Dash ||
code === CharCode.Period ||
code === CharCode.Underline ||
code === CharCode.Tilde ||
(allowSlash && code === CharCode.Slash)
) {
// check if we are delaying native encode
if (nativeEncodePos !== -1) {
res += encodeURIComponent(uriComponent.substring(nativeEncodePos, pos));
nativeEncodePos = -1;
}
// check if we write into a new string (by default we try to return the param)
if (res !== undefined) {
res += uriComponent.charAt(pos);
}
} else {
// encoding needed, we need to allocate a new string
if (res === undefined) {
res = uriComponent.substr(0, pos);
}
// check with default table first
const escaped = encodeTable[code];
if (escaped !== undefined) {
// check if we are delaying native encode
if (nativeEncodePos !== -1) {
res += encodeURIComponent(
uriComponent.substring(nativeEncodePos, pos)
);
nativeEncodePos = -1;
}
// append escaped variant to result
res += escaped;
} else if (nativeEncodePos === -1) {
// use native encode only when needed
nativeEncodePos = pos;
}
}
}
if (nativeEncodePos !== -1) {
res += encodeURIComponent(uriComponent.substring(nativeEncodePos));
}
return res !== undefined ? res : uriComponent;
}
function encodeURIComponentMinimal(path: string): string {
let res: string | undefined = undefined;
for (let pos = 0; pos < path.length; pos++) {
const code = path.charCodeAt(pos);
if (code === CharCode.Hash || code === CharCode.QuestionMark) {
if (res === undefined) {
res = path.substr(0, pos);
}
res += encodeTable[code];
} else {
if (res !== undefined) {
res += path[pos];
}
}
}
return res !== undefined ? res : path;
}
/**
* Compute `fsPath` for the given uri
*/
export function uriToFsPath(uri: URI, keepDriveLetterCasing: boolean): string {
let value: string;
if (uri.authority && uri.path.length > 1 && uri.scheme === 'file') {
// unc path: file://shares/c$/far/boo
value = `//${uri.authority}${uri.path}`;
} else if (
uri.path.charCodeAt(0) === CharCode.Slash &&
((uri.path.charCodeAt(1) >= CharCode.A &&
uri.path.charCodeAt(1) <= CharCode.Z) ||
(uri.path.charCodeAt(1) >= CharCode.a &&
uri.path.charCodeAt(1) <= CharCode.z)) &&
uri.path.charCodeAt(2) === CharCode.Colon
) {
if (!keepDriveLetterCasing) {
// windows drive letter: file:///c:/far/boo
value = uri.path[1].toLowerCase() + uri.path.substr(2);
} else {
value = uri.path.substr(1);
}
} else {
// other path
value = uri.path;
}
if (isWindows) {
value = value.replace(/\//g, '\\');
}
return value;
}
/**
* Create the external version of a uri
*/
function _asFormatted(uri: URI, skipEncoding: boolean): string {
const encoder = !skipEncoding
? encodeURIComponentFast
: encodeURIComponentMinimal;
let res = '';
let { scheme, authority, path, query, fragment } = uri;
if (scheme) {
res += scheme;
res += ':';
}
if (authority || scheme === 'file') {
res += _slash;
res += _slash;
}
if (authority) {
let idx = authority.indexOf('@');
if (idx !== -1) {
// <user>@<auth>
const userinfo = authority.substr(0, idx);
authority = authority.substr(idx + 1);
idx = userinfo.indexOf(':');
if (idx === -1) {
res += encoder(userinfo, false);
} else {
// <user>:<pass>@<auth>
res += encoder(userinfo.substr(0, idx), false);
res += ':';
res += encoder(userinfo.substr(idx + 1), false);
}
res += '@';
}
authority = authority.toLowerCase();
idx = authority.indexOf(':');
if (idx === -1) {
res += encoder(authority, false);
} else {
// <auth>:<port>
res += encoder(authority.substr(0, idx), false);
res += authority.substr(idx);
}
}
if (path) {
// lower-case windows drive letters in /C:/fff or C:/fff
if (
path.length >= 3 &&
path.charCodeAt(0) === CharCode.Slash &&
path.charCodeAt(2) === CharCode.Colon
) {
const code = path.charCodeAt(1);
if (code >= CharCode.A && code <= CharCode.Z) {
path = `/${String.fromCharCode(code + 32)}:${path.substr(3)}`; // "/c:".length === 3
}
} else if (path.length >= 2 && path.charCodeAt(1) === CharCode.Colon) {
const code = path.charCodeAt(0);
if (code >= CharCode.A && code <= CharCode.Z) {
path = `${String.fromCharCode(code + 32)}:${path.substr(2)}`; // "/c:".length === 3
}
}
// encode the rest of the path
res += encoder(path, true);
}
if (query) {
res += '?';
res += encoder(query, false);
}
if (fragment) {
res += '#';
res += !skipEncoding ? encodeURIComponentFast(fragment, false) : fragment;
}
return res;
}
// --- decode
function decodeURIComponentGraceful(str: string): string {
try {
return decodeURIComponent(str);
} catch {
if (str.length > 3) {
return str.substr(0, 3) + decodeURIComponentGraceful(str.substr(3));
} else {
return str;
}
}
}
const _rEncodedAsHex = /(%[0-9A-Za-z][0-9A-Za-z])+/g;
function percentDecode(str: string): string {
if (!str.match(_rEncodedAsHex)) {
return str;
}
return str.replace(_rEncodedAsHex, match =>
decodeURIComponentGraceful(match)
);
}

View File

@@ -1,84 +0,0 @@
import {
Resource,
Attachment,
Placeholder,
Note,
NoteLink,
isNote,
NoteLinkDefinition,
isPlaceholder,
isAttachment,
getTitle,
NoteParser,
} from './model/note';
import { Position } from './model/position';
import { Range } from './model/range';
import { URI } from './common/uri';
import { FoamConfig } from './config';
import { IDataStore, FileDataStore } from './services/datastore';
import { ILogger } from './utils/log';
import { IDisposable, isDisposable } from './common/lifecycle';
import { FoamWorkspace } from './model/workspace';
import * as uris from './utils/uri';
import * as positions from './model/position';
import * as ranges from './model/range';
export { uris, positions, ranges };
export { IDataStore, FileDataStore };
export { ILogger };
export { LogLevel, LogLevelThreshold, Logger, BaseLogger } from './utils/log';
export { Event, Emitter } from './common/event';
export { FoamConfig };
export { isSameUri, parseUri } from './utils/uri';
export { IDisposable, isDisposable };
export {
createMarkdownReferences,
stringifyMarkdownLinkReferenceDefinition,
createMarkdownParser,
} from './markdown-provider';
export {
TextEdit,
generateHeading,
generateLinkReferences,
getKebabCaseFileName,
LINK_REFERENCE_DEFINITION_HEADER,
LINK_REFERENCE_DEFINITION_FOOTER,
} from './janitor';
export { applyTextEdit } from './janitor/apply-text-edit';
export { createConfigFromFolders } from './config';
export { bootstrap } from './bootstrap';
export {
Resource,
Attachment,
Placeholder,
Note,
Position,
Range,
NoteLink,
URI,
FoamWorkspace,
NoteLinkDefinition,
NoteParser,
isNote,
isPlaceholder,
isAttachment,
getTitle,
};
export interface Services {
dataStore: IDataStore;
parser: NoteParser;
}
export interface Foam extends IDisposable {
services: Services;
workspace: FoamWorkspace;
config: FoamConfig;
}

View File

@@ -1,341 +0,0 @@
import { Node, Position as AstPosition } from 'unist';
import unified from 'unified';
import markdownParse from 'remark-parse';
import wikiLinkPlugin from 'remark-wiki-link';
import frontmatterPlugin from 'remark-frontmatter';
import { parse as parseYAML } from 'yaml';
import visit from 'unist-util-visit';
import { Parent, Point } from 'unist';
import detectNewline from 'detect-newline';
import os from 'os';
import {
NoteLinkDefinition,
Note,
NoteParser,
isWikilink,
getTitle,
} from './model/note';
import { Position, create as createPos } from './model/position';
import { Range, create as createRange } from './model/range';
import {
dropExtension,
extractHashtags,
extractTagsFromProp,
isNone,
isSome,
} from './utils';
import { computeRelativePath, getBasename, parseUri } from './utils/uri';
import { ParserPlugin } from './plugins';
import { Logger } from './utils/log';
import { URI } from './common/uri';
import { FoamWorkspace } from './model/workspace';
/**
* Traverses all the children of the given node, extracts
* the text from them, and returns it concatenated.
*
* @param root the node from which to start collecting text
*/
const getTextFromChildren = (root: Node): string => {
let text = '';
visit(root, 'text', node => {
if (node.type === 'text') {
text = text + node.value;
}
});
return text;
};
const tagsPlugin: ParserPlugin = {
name: 'tags',
onWillVisitTree: (tree, note) => {
note.tags = extractHashtags(note.source.text);
},
onDidFindProperties: (props, note) => {
const yamlTags = extractTagsFromProp(props.tags);
yamlTags.forEach(tag => note.tags.add(tag));
},
};
const titlePlugin: ParserPlugin = {
name: 'title',
visit: (node, note) => {
if (note.title == null && node.type === 'heading' && node.depth === 1) {
note.title =
((node as Parent)!.children?.[0]?.value as string) || note.title;
}
},
onDidFindProperties: (props, note) => {
// Give precendence to the title from the frontmatter if it exists
note.title = props.title ?? note.title;
},
onDidVisitTree: (tree, note) => {
if (note.title == null) {
note.title = getBasename(note.uri);
}
},
};
const wikilinkPlugin: ParserPlugin = {
name: 'wikilink',
visit: (node, note) => {
if (node.type === 'wikiLink') {
note.links.push({
type: 'wikilink',
slug: node.value as string,
target: node.value as string,
range: astPositionToFoamRange(node.position!),
});
}
if (node.type === 'link') {
const targetUri = (node as any).url;
const uri = parseUri(note.uri, targetUri);
if (uri.scheme !== 'file' || uri.path === note.uri.path) {
return;
}
const label = getTextFromChildren(node);
note.links.push({
type: 'link',
target: targetUri,
label: label,
range: astPositionToFoamRange(node.position!),
});
}
},
};
const definitionsPlugin: ParserPlugin = {
name: 'definitions',
visit: (node, note) => {
if (node.type === 'definition') {
note.definitions.push({
label: node.label as string,
url: node.url as string,
title: node.title as string,
range: astPositionToFoamRange(node.position!),
});
}
},
onDidVisitTree: (tree, note) => {
note.definitions = getFoamDefinitions(note.definitions, note.source.end);
},
};
const handleError = (
plugin: ParserPlugin,
fnName: string,
uri: URI | undefined,
e: Error
): void => {
const name = plugin.name || '';
Logger.warn(
`Error while executing [${fnName}] in plugin [${name}] for file [${uri?.path}]`,
e
);
};
export function createMarkdownParser(extraPlugins: ParserPlugin[]): NoteParser {
const parser = unified()
.use(markdownParse, { gfm: true })
.use(frontmatterPlugin, ['yaml'])
.use(wikiLinkPlugin);
const plugins = [
titlePlugin,
wikilinkPlugin,
definitionsPlugin,
tagsPlugin,
...extraPlugins,
];
plugins.forEach(plugin => {
try {
plugin.onDidInitializeParser?.(parser);
} catch (e) {
handleError(plugin, 'onDidInitializeParser', undefined, e);
}
});
const foamParser: NoteParser = {
parse: (uri: URI, markdown: string): Note => {
Logger.debug('Parsing:', uri);
markdown = plugins.reduce((acc, plugin) => {
try {
return plugin.onWillParseMarkdown?.(acc) || acc;
} catch (e) {
handleError(plugin, 'onWillParseMarkdown', uri, e);
return acc;
}
}, markdown);
const tree = parser.parse(markdown);
const eol = detectNewline(markdown) || os.EOL;
var note: Note = {
uri: uri,
type: 'note',
properties: {},
title: null,
tags: new Set(),
links: [],
definitions: [],
source: {
text: markdown,
contentStart: astPointToFoamPosition(tree.position!.start),
end: astPointToFoamPosition(tree.position!.end),
eol: eol,
},
};
plugins.forEach(plugin => {
try {
plugin.onWillVisitTree?.(tree, note);
} catch (e) {
handleError(plugin, 'onWillVisitTree', uri, e);
}
});
visit(tree, node => {
if (node.type === 'yaml') {
try {
const yamlProperties = parseYAML(node.value as string) ?? {};
note.properties = {
...note.properties,
...yamlProperties,
};
// Give precendence to the title from the frontmatter if it exists
note.title = note.properties.title ?? note.title;
// Update the start position of the note by exluding the metadata
note.source.contentStart = createPos(
node.position!.end.line! + 2,
0
);
for (let i = 0, len = plugins.length; i < len; i++) {
try {
plugins[i].onDidFindProperties?.(yamlProperties, note);
} catch (e) {
handleError(plugins[i], 'onDidFindProperties', uri, e);
}
}
} catch (e) {
Logger.warn(`Error while parsing YAML for [${uri}]`, e);
}
}
for (let i = 0, len = plugins.length; i < len; i++) {
try {
plugins[i].visit?.(node, note);
} catch (e) {
handleError(plugins[i], 'visit', uri, e);
}
}
});
plugins.forEach(plugin => {
try {
plugin.onDidVisitTree?.(tree, note);
} catch (e) {
handleError(plugin, 'onDidVisitTree', uri, e);
}
});
Logger.debug('Result:', note);
return note;
},
};
return foamParser;
}
function getFoamDefinitions(
defs: NoteLinkDefinition[],
fileEndPoint: Position
): NoteLinkDefinition[] {
let previousLine = fileEndPoint.line;
let foamDefinitions = [];
// walk through each definition in reverse order
// (last one first)
for (const def of defs.reverse()) {
// if this definition is more than 2 lines above the
// previous one below it (or file end), that means we
// have exited the trailing definition block, and should bail
const start = def.range!.start.line;
if (start < previousLine - 2) {
break;
}
foamDefinitions.unshift(def);
previousLine = def.range!.end.line;
}
return foamDefinitions;
}
export function stringifyMarkdownLinkReferenceDefinition(
definition: NoteLinkDefinition
) {
let text = `[${definition.label}]: ${definition.url}`;
if (definition.title) {
text = `${text} "${definition.title}"`;
}
return text;
}
export function createMarkdownReferences(
workspace: FoamWorkspace,
noteUri: URI,
includeExtension: boolean
): NoteLinkDefinition[] {
const source = workspace.find(noteUri);
// Should never occur since we're already in a file,
if (source?.type !== 'note') {
console.warn(
`Note ${noteUri} note found in workspace when attempting to generate markdown reference list`
);
return [];
}
return source.links
.filter(isWikilink)
.map(link => {
const targetUri = workspace.resolveLink(source, link);
const target = workspace.find(targetUri);
if (isNone(target)) {
Logger.warn(`Link ${targetUri} in ${noteUri} is not valid.`);
return null;
}
if (target.type === 'placeholder') {
// no need to create definitions for placeholders
return null;
}
const relativePath = computeRelativePath(noteUri, target.uri);
const pathToNote = includeExtension
? relativePath
: dropExtension(relativePath);
// [wiki-link-text]: path/to/file.md "Page title"
return { label: link.slug, url: pathToNote, title: getTitle(target) };
})
.filter(isSome)
.sort();
}
/**
* Converts the 1-index Point object into the VS Code 0-index Position object
* @param point ast Point (1-indexed)
* @returns Foam Position (0-indexed)
*/
const astPointToFoamPosition = (point: Point): Position => {
return createPos(point.line - 1, point.column - 1);
};
/**
* Converts the 1-index Position object into the VS Code 0-index Range object
* @param position an ast Position object (1-indexed)
* @returns Foam Range (0-indexed)
*/
const astPositionToFoamRange = (pos: AstPosition): Range =>
createRange(
pos.start.line - 1,
pos.start.column - 1,
pos.end.line - 1,
pos.end.column - 1
);

View File

@@ -1,85 +0,0 @@
import { URI } from '../common/uri';
import { getBasename } from '../utils/uri';
import { Position } from './position';
import { Range } from './range';
export interface NoteSource {
text: string;
contentStart: Position;
end: Position;
eol: string;
}
export interface WikiLink {
type: 'wikilink';
slug: string;
target: string;
range: Range;
}
export interface DirectLink {
type: 'link';
label: string;
target: string;
range: Range;
}
export type NoteLink = WikiLink | DirectLink;
export interface NoteLinkDefinition {
label: string;
url: string;
title?: string;
range?: Range;
}
export interface BaseResource {
uri: URI;
}
export interface Attachment extends BaseResource {
type: 'attachment';
}
export interface Placeholder extends BaseResource {
type: 'placeholder';
}
export interface Note extends BaseResource {
type: 'note';
title: string | null;
properties: any;
// sections: NoteSection[]
tags: Set<string>;
links: NoteLink[];
definitions: NoteLinkDefinition[];
source: NoteSource;
}
export type Resource = Note | Attachment | Placeholder;
export interface NoteParser {
parse: (uri: URI, text: string) => Note;
}
export const isWikilink = (link: NoteLink): link is WikiLink => {
return link.type === 'wikilink';
};
export const getTitle = (resource: Resource): string => {
return resource.type === 'note'
? resource.title ?? getBasename(resource.uri)
: getBasename(resource.uri);
};
export const isNote = (resource: Resource): resource is Note => {
return resource.type === 'note';
};
export const isPlaceholder = (resource: Resource): resource is Placeholder => {
return resource.type === 'placeholder';
};
export const isAttachment = (resource: Resource): resource is Attachment => {
return resource.type === 'attachment';
};

View File

@@ -1,87 +0,0 @@
export interface Position {
line: number;
character: number;
}
export const create = (line: number, character: number): Position => ({
line,
character,
});
export const Min = (...positions: Position[]): Position => {
if (positions.length === 0) {
throw new TypeError();
}
let result = positions[0];
for (let i = 1; i < positions.length; i++) {
const p = positions[i];
if (isBefore(p, result!)) {
result = p;
}
}
return result;
};
export const Max = (...positions: Position[]): Position => {
if (positions.length === 0) {
throw new TypeError();
}
let result = positions[0];
for (let i = 1; i < positions.length; i++) {
const p = positions[i];
if (isAfter(p, result!)) {
result = p;
}
}
return result;
};
export const isBefore = (p1: Position, p2: Position): boolean => {
if (p1.line < p2.line) {
return true;
}
if (p2.line < p1.line) {
return false;
}
return p1.character < p2.character;
};
export const isBeforeOrEqual = (p1: Position, p2: Position): boolean => {
if (p1.line < p2.line) {
return true;
}
if (p2.line < p1.line) {
return false;
}
return p1.character <= p2.character;
};
export const isAfter = (p1: Position, p2: Position): boolean => {
return !isBeforeOrEqual(p1, p2);
};
export const isAfterOrEqual = (p1: Position, p2: Position): boolean => {
return !isBefore(p1, p2);
};
export const isEqual = (p1: Position, p2: Position): boolean => {
return p1.line === p2.line && p1.character === p2.character;
};
export const compareTo = (p1: Position, p2: Position): number => {
if (p1.line < p2.line) {
return -1;
} else if (p1.line > p2.line) {
return 1;
} else {
// equal line
if (p1.character < p2.character) {
return -1;
} else if (p1.character > p2.character) {
return 1;
} else {
// equal line and character
return 0;
}
}
};

View File

@@ -1,55 +0,0 @@
import { Position } from './position';
import * as pos from './position';
export interface Range {
start: Position;
end: Position;
}
export const create = (
startLine: number,
startChar: number,
endLine?: number,
endChar?: number
): Range => {
const start: Position = {
line: startLine,
character: startChar,
};
const end: Position = {
line: endLine ?? startLine,
character: endChar ?? startChar,
};
return createFromPosition(start, end);
};
export const createFromPosition = (start: Position, end?: Position) => {
end = end ?? start;
let first = start;
let second = end;
if (pos.isAfter(start, end)) {
first = end;
second = start;
}
return {
start: {
line: first.line,
character: first.character,
},
end: {
line: second.line,
character: second.character,
},
};
};
export const containsRange = (range: Range, contained: Range): boolean =>
containsPosition(range, contained.start) &&
containsPosition(range, contained.end);
export const containsPosition = (range: Range, position: Position): boolean =>
pos.isAfterOrEqual(position, range.start) &&
pos.isBeforeOrEqual(position, range.end);
export const isEqual = (r1: Range, r2: Range): boolean =>
pos.isEqual(r1.start, r2.start) && pos.isEqual(r1.end, r2.end);

View File

@@ -1,494 +0,0 @@
import { diff } from 'fast-array-diff';
import { isEqual } from 'lodash';
import * as path from 'path';
import { URI } from '../common/uri';
import { Resource, NoteLink, Note } from './note';
import * as ranges from './range';
import {
computeRelativeURI,
isSome,
isNone,
parseUri,
placeholderUri,
isPlaceholder,
isSameUri,
} from '../utils';
import { Emitter } from '../common/event';
import { IDisposable } from '../index';
export type Connection = {
source: URI;
target: URI;
link: NoteLink;
};
export function getReferenceType(
reference: URI | string
): 'uri' | 'absolute-path' | 'relative-path' | 'key' {
if (URI.isUri(reference)) {
return 'uri';
}
const isPath = reference.split('/').length > 1;
if (!isPath) {
return 'key';
}
const isAbsPath = isPath && reference.startsWith('/');
return isAbsPath ? 'absolute-path' : 'relative-path';
}
const pathToResourceId = (pathValue: string) => {
const { ext } = path.parse(pathValue);
return ext.length > 0 ? pathValue : pathValue + '.md';
};
const uriToResourceId = (uri: URI) => pathToResourceId(uri.path);
const pathToResourceName = (pathValue: string) => path.parse(pathValue).name;
const uriToResourceName = (uri: URI) => pathToResourceName(uri.path);
const pathToPlaceholderId = (value: string) => value;
const uriToPlaceholderId = (uri: URI) => pathToPlaceholderId(uri.path);
export class FoamWorkspace implements IDisposable {
private onDidAddEmitter = new Emitter<Resource>();
private onDidUpdateEmitter = new Emitter<{ old: Resource; new: Resource }>();
private onDidDeleteEmitter = new Emitter<Resource>();
onDidAdd = this.onDidAddEmitter.event;
onDidUpdate = this.onDidUpdateEmitter.event;
onDidDelete = this.onDidDeleteEmitter.event;
/**
* Resources by key / slug
*/
private resourcesByName: { [key: string]: string[] } = {};
/**
* Resources by URI
*/
private resources: { [key: string]: Resource } = {};
/**
* Placehoders by key / slug / value
*/
private placeholders: { [key: string]: Resource } = {};
/**
* Maps the connections starting from a URI
*/
private links: { [key: string]: Connection[] } = {};
/**
* Maps the connections arriving to a URI
*/
private backlinks: { [key: string]: Connection[] } = {};
/**
* List of disposables to destroy with the workspace
*/
disposables: IDisposable[] = [];
exists(uri: URI) {
return FoamWorkspace.exists(this, uri);
}
list() {
return FoamWorkspace.list(this);
}
get(uri: URI) {
return FoamWorkspace.get(this, uri);
}
find(uri: URI | string) {
return FoamWorkspace.find(this, uri);
}
set(resource: Resource) {
return FoamWorkspace.set(this, resource);
}
delete(uri: URI) {
return FoamWorkspace.delete(this, uri);
}
resolveLink(note: Note, link: NoteLink) {
return FoamWorkspace.resolveLink(this, note, link);
}
resolveLinks(keepMonitoring: boolean = false) {
return FoamWorkspace.resolveLinks(this, keepMonitoring);
}
getAllConnections() {
return FoamWorkspace.getAllConnections(this);
}
getConnections(uri: URI) {
return FoamWorkspace.getConnections(this, uri);
}
getLinks(uri: URI) {
return FoamWorkspace.getLinks(this, uri);
}
getBacklinks(uri: URI) {
return FoamWorkspace.getBacklinks(this, uri);
}
dispose(): void {
this.onDidAddEmitter.dispose();
this.onDidDeleteEmitter.dispose();
this.onDidUpdateEmitter.dispose();
this.disposables.forEach(d => d.dispose());
}
public static resolveLink(
workspace: FoamWorkspace,
note: Note,
link: NoteLink
): URI {
let targetUri: URI | undefined;
switch (link.type) {
case 'wikilink':
const definitionUri = note.definitions.find(
def => def.label === link.slug
)?.url;
if (isSome(definitionUri)) {
const definedUri = parseUri(note.uri, definitionUri);
targetUri =
FoamWorkspace.find(workspace, definedUri, note.uri)?.uri ??
placeholderUri(definedUri.path);
} else {
targetUri =
FoamWorkspace.find(workspace, link.slug, note.uri)?.uri ??
placeholderUri(link.slug);
}
break;
case 'link':
targetUri =
FoamWorkspace.find(workspace, link.target, note.uri)?.uri ??
placeholderUri(parseUri(note.uri, link.target).path);
break;
}
if (isPlaceholder(targetUri)) {
// we can only add placeholders when links are being resolved
workspace = FoamWorkspace.set(workspace, {
type: 'placeholder',
uri: targetUri,
});
}
return targetUri;
}
/**
* Computes all the links in the workspace, connecting notes and
* creating placeholders.
*
* @param workspace the target workspace
* @param keepMonitoring whether to recompute the links when the workspace changes
* @returns the resolved workspace
*/
public static resolveLinks(
workspace: FoamWorkspace,
keepMonitoring: boolean = false
): FoamWorkspace {
workspace.links = {};
workspace.backlinks = {};
workspace.placeholders = {};
workspace = Object.values(workspace.list()).reduce(
(w, resource) => FoamWorkspace.resolveResource(w, resource),
workspace
);
if (keepMonitoring) {
workspace.disposables.push(
workspace.onDidAdd(resource => {
FoamWorkspace.updateLinksRelatedToAddedResource(workspace, resource);
}),
workspace.onDidUpdate(change => {
FoamWorkspace.updateLinksForResource(
workspace,
change.old,
change.new
);
}),
workspace.onDidDelete(resource => {
FoamWorkspace.updateLinksRelatedToDeletedResource(
workspace,
resource
);
})
);
}
return workspace;
}
public static getAllConnections(workspace: FoamWorkspace): Connection[] {
return Object.values(workspace.links).flat();
}
public static getConnections(
workspace: FoamWorkspace,
uri: URI
): Connection[] {
return [
...(workspace.links[uri.path] || []),
...(workspace.backlinks[uri.path] || []),
];
}
public static getLinks(workspace: FoamWorkspace, uri: URI): Connection[] {
return workspace.links[uri.path] ?? [];
}
public static getBacklinks(workspace: FoamWorkspace, uri: URI): Connection[] {
return workspace.backlinks[uri.path] ?? [];
}
public static set(
workspace: FoamWorkspace,
resource: Resource
): FoamWorkspace {
if (resource.type === 'placeholder') {
workspace.placeholders[uriToPlaceholderId(resource.uri)] = resource;
return workspace;
}
const id = uriToResourceId(resource.uri);
const old = FoamWorkspace.find(workspace, resource.uri);
const name = uriToResourceName(resource.uri);
workspace.resources[id] = resource;
workspace.resourcesByName[name] = workspace.resourcesByName[name] ?? [];
workspace.resourcesByName[name].push(id);
isSome(old)
? workspace.onDidUpdateEmitter.fire({ old: old, new: resource })
: workspace.onDidAddEmitter.fire(resource);
return workspace;
}
public static exists(workspace: FoamWorkspace, uri: URI): boolean {
return isSome(workspace.resources[uriToResourceId(uri)]);
}
public static list(workspace: FoamWorkspace): Resource[] {
return [
...Object.values(workspace.resources),
...Object.values(workspace.placeholders),
];
}
public static get(workspace: FoamWorkspace, uri: URI): Resource {
const note = FoamWorkspace.find(workspace, uri);
if (isSome(note)) {
return note;
} else {
throw new Error('Resource not found: ' + uri.path);
}
}
public static find(
workspace: FoamWorkspace,
resourceId: URI | string,
reference?: URI
): Resource | null {
const refType = getReferenceType(resourceId);
switch (refType) {
case 'uri':
const uri = resourceId as URI;
if (uri.scheme === 'placeholder') {
return uri.path in workspace.placeholders
? { type: 'placeholder', uri: uri }
: null;
} else {
return FoamWorkspace.exists(workspace, uri)
? workspace.resources[uriToResourceId(uri)]
: null;
}
case 'key':
const name = pathToResourceName(resourceId as string);
const paths = workspace.resourcesByName[name];
if (isNone(paths) || paths.length === 0) {
const placeholderId = pathToPlaceholderId(resourceId as string);
return workspace.placeholders[placeholderId] ?? null;
}
// prettier-ignore
const sortedPaths = paths.length === 1
? paths
: paths.sort((a, b) => a.localeCompare(b));
return workspace.resources[sortedPaths[0]];
case 'absolute-path':
const resourceUri = URI.file(resourceId as string);
return (
workspace.resources[uriToResourceId(resourceUri)] ??
workspace.placeholders[uriToPlaceholderId(resourceUri)]
);
case 'relative-path':
if (isNone(reference)) {
return null;
}
const relativePath = resourceId as string;
const targetUri = computeRelativeURI(reference, relativePath);
return (
workspace.resources[uriToResourceId(targetUri)] ??
workspace.placeholders[pathToPlaceholderId(resourceId as string)]
);
default:
throw new Error('Unexpected reference type: ' + refType);
}
}
public static delete(workspace: FoamWorkspace, uri: URI): Resource | null {
const id = uriToResourceId(uri);
const deleted = workspace.resources[id];
delete workspace.resources[id];
const name = uriToResourceName(uri);
workspace.resourcesByName[name] =
workspace.resourcesByName[name]?.filter(resId => resId !== id) ?? [];
if (workspace.resourcesByName[name].length === 0) {
delete workspace.resourcesByName[name];
}
isSome(deleted) && workspace.onDidDeleteEmitter.fire(deleted);
return deleted ?? null;
}
public static resolveResource(workspace: FoamWorkspace, resource: Resource) {
if (resource.type === 'note') {
delete workspace.links[resource.uri.path];
// prettier-ignore
resource.links.forEach(link => {
const targetUri = FoamWorkspace.resolveLink(workspace, resource, link);
workspace = FoamWorkspace.connect(workspace, resource.uri, targetUri, link);
});
}
return workspace;
}
private static updateLinksForResource(
workspace: FoamWorkspace,
oldResource: Resource,
newResource: Resource
) {
if (oldResource.uri.path !== newResource.uri.path) {
throw new Error(
'Unexpected State: update should only be called on same resource ' +
{
old: oldResource,
new: newResource,
}
);
}
if (oldResource.type === 'note' && newResource.type === 'note') {
const patch = diff(oldResource.links, newResource.links, isEqual);
workspace = patch.removed.reduce((ws, link) => {
const target = ws.resolveLink(oldResource, link);
return FoamWorkspace.disconnect(ws, oldResource.uri, target, link);
}, workspace);
workspace = patch.added.reduce((ws, link) => {
const target = ws.resolveLink(newResource, link);
return FoamWorkspace.connect(ws, newResource.uri, target, link);
}, workspace);
}
return workspace;
}
private static updateLinksRelatedToAddedResource(
workspace: FoamWorkspace,
resource: Resource
) {
// check if any existing connection can be filled by new resource
const name = uriToResourceName(resource.uri);
if (name in workspace.placeholders) {
const placeholder = workspace.placeholders[name];
delete workspace.placeholders[name];
const resourcesToUpdate = workspace.backlinks[placeholder.uri.path] ?? [];
workspace = resourcesToUpdate.reduce(
(ws, res) => FoamWorkspace.resolveResource(ws, ws.get(res.source)),
workspace
);
}
// resolve the resource
workspace = FoamWorkspace.resolveResource(workspace, resource);
}
private static updateLinksRelatedToDeletedResource(
workspace: FoamWorkspace,
resource: Resource
) {
const uri = resource.uri;
// remove forward links from old resource
const resourcesPointedByDeletedNote = workspace.links[uri.path] ?? [];
delete workspace.links[uri.path];
workspace = resourcesPointedByDeletedNote.reduce(
(ws, connection) =>
FoamWorkspace.disconnect(ws, uri, connection.target, connection.link),
workspace
);
// recompute previous links to old resource
const notesPointingToDeletedResource = workspace.backlinks[uri.path] ?? [];
delete workspace.backlinks[uri.path];
workspace = notesPointingToDeletedResource.reduce(
(ws, link) => FoamWorkspace.resolveResource(ws, ws.get(link.source)),
workspace
);
return workspace;
}
private static connect(
workspace: FoamWorkspace,
source: URI,
target: URI,
link: NoteLink
) {
const connection = { source, target, link };
workspace.links[source.path] = workspace.links[source.path] ?? [];
workspace.links[source.path].push(connection);
workspace.backlinks[target.path] = workspace.backlinks[target.path] ?? [];
workspace.backlinks[target.path].push(connection);
return workspace;
}
/**
* Removes a connection, or all connections, between the source and
* target resources
*
* @param workspace the Foam workspace
* @param source the source resource
* @param target the target resource
* @param link the link reference, or `true` to remove all links
* @returns the updated Foam workspace
*/
private static disconnect(
workspace: FoamWorkspace,
source: URI,
target: URI,
link: NoteLink | true
) {
const connectionsToKeep =
link === true
? (c: Connection) =>
!isSameUri(source, c.source) || !isSameUri(target, c.target)
: (c: Connection) => !isSameConnection({ source, target, link }, c);
workspace.links[source.path] =
workspace.links[source.path]?.filter(connectionsToKeep) ?? [];
if (workspace.links[source.path].length === 0) {
delete workspace.links[source.path];
}
workspace.backlinks[target.path] =
workspace.backlinks[target.path]?.filter(connectionsToKeep) ?? [];
if (workspace.backlinks[target.path].length === 0) {
delete workspace.backlinks[target.path];
if (isPlaceholder(target)) {
delete workspace.placeholders[uriToPlaceholderId(target)];
}
}
return workspace;
}
}
// TODO move these utility fns to appropriate places
const isSameConnection = (a: Connection, b: Connection) =>
isSameUri(a.source, b.source) &&
isSameUri(a.target, b.target) &&
isSameLink(a.link, b.link);
const isSameLink = (a: NoteLink, b: NoteLink) =>
a.type === b.type && ranges.isEqual(a.range, b.range);

View File

@@ -1,86 +0,0 @@
import * as fs from 'fs';
import path from 'path';
import { Node } from 'unist';
import { isNotNull } from '../utils';
import { Note } from '../model/note';
import unified from 'unified';
import { FoamConfig } from '../config';
import { Logger } from '../utils/log';
import { URI } from '../common/uri';
export interface FoamPlugin {
name: string;
description?: string;
parser?: ParserPlugin;
}
export interface ParserPlugin {
name?: string;
visit?: (node: Node, note: Note) => void;
onDidInitializeParser?: (parser: unified.Processor) => void;
onWillParseMarkdown?: (markdown: string) => string;
onWillVisitTree?: (tree: Node, note: Note) => void;
onDidVisitTree?: (tree: Node, note: Note) => void;
onDidFindProperties?: (properties: any, note: Note) => void;
}
export interface PluginConfig {
enabled?: boolean;
pluginFolders?: string[];
}
export const SETTINGS_PATH = 'experimental.localPlugins';
export async function loadPlugins(config: FoamConfig): Promise<FoamPlugin[]> {
const pluginConfig = config.get<PluginConfig>(SETTINGS_PATH, {});
const isFeatureEnabled = pluginConfig.enabled ?? false;
if (!isFeatureEnabled) {
return [];
}
const pluginDirs: URI[] =
pluginConfig.pluginFolders?.map(URI.file) ??
findPluginDirs(config.workspaceFolders);
const plugins = await Promise.all(
pluginDirs
.filter(dir => fs.statSync(dir.fsPath).isDirectory)
.map(async dir => {
try {
const pluginFile = path.join(dir.fsPath, 'index.js');
fs.accessSync(pluginFile);
Logger.info(`Found plugin at [${pluginFile}]. Loading..`);
const plugin = validate(await import(pluginFile));
return plugin;
} catch (e) {
Logger.error(`Error while loading plugin at [${dir}] - skipping`, e);
return null;
}
})
);
return plugins.filter(isNotNull);
}
function findPluginDirs(workspaceFolders: URI[]) {
return workspaceFolders
.map(root => URI.joinPath(root, '.foam', 'plugins'))
.reduce((acc, pluginDir) => {
try {
const content = fs
.readdirSync(pluginDir.fsPath)
.map(dir => URI.joinPath(pluginDir, dir));
return [
...acc,
...content.filter(c => fs.statSync(c.fsPath).isDirectory()),
];
} catch {
return acc;
}
}, [] as URI[]);
}
function validate(plugin: any): FoamPlugin {
if (!plugin.name) {
throw new Error('Plugin must export `name` string property');
}
return plugin;
}

View File

@@ -1,175 +0,0 @@
import glob from 'glob';
import { promisify } from 'util';
import micromatch from 'micromatch';
import fs from 'fs';
import { Event, Emitter } from '../common/event';
import { URI } from '../common/uri';
import { FoamConfig } from '../config';
import { Logger } from '../utils/log';
import { isSome } from '../utils';
import { IDisposable } from '../common/lifecycle';
const findAllFiles = promisify(glob);
export interface IWatcher {
/**
* An event which fires on file creation.
*/
onDidCreate: Event<URI>;
/**
* An event which fires on file change.
*/
onDidChange: Event<URI>;
/**
* An event which fires on file deletion.
*/
onDidDelete: Event<URI>;
}
/**
* Represents a source of files and content
*/
export interface IDataStore {
/**
* List the files available in the store
*/
listFiles: () => Promise<URI[]>;
/**
* Read the content of the file from the store
*/
read: (uri: URI) => Promise<string>;
/**
* Returns whether the given URI is a match in
* this data store
*/
isMatch: (uri: URI) => boolean;
/**
* An event which fires on file creation.
*/
onDidCreate: Event<URI>;
/**
* An event which fires on file change.
*/
onDidChange: Event<URI>;
/**
* An event which fires on file deletion.
*/
onDidDelete: Event<URI>;
}
/**
* File system based data store
*/
export class FileDataStore implements IDataStore, IDisposable {
readonly onDidChangeEmitter = new Emitter<URI>();
readonly onDidCreateEmitter = new Emitter<URI>();
readonly onDidDeleteEmitter = new Emitter<URI>();
readonly onDidCreate: Event<URI> = this.onDidCreateEmitter.event;
readonly onDidChange: Event<URI> = this.onDidChangeEmitter.event;
readonly onDidDelete: Event<URI> = this.onDidDeleteEmitter.event;
private _folders: readonly string[];
private _includeGlobs: string[] = [];
private _ignoreGlobs: string[] = [];
private _disposables: IDisposable[] = [];
constructor(config: FoamConfig, watcher?: IWatcher) {
this._folders = config.workspaceFolders.map(f =>
f.fsPath.replace(/\\/g, '/')
);
Logger.info('Workspace folders: ', this._folders);
this._folders.forEach(folder => {
const withFolder = folderPlusGlob(folder);
this._includeGlobs.push(
...config.includeGlobs.map(glob => {
if (glob.endsWith('*')) {
glob = `${glob}\\.(md|mdx|markdown)`;
}
return withFolder(glob);
})
);
this._ignoreGlobs.push(...config.ignoreGlobs.map(withFolder));
});
Logger.info('Glob patterns', {
includeGlobs: this._includeGlobs,
ignoreGlobs: this._ignoreGlobs,
});
if (isSome(watcher)) {
this._disposables.push(
watcher.onDidCreate(uri => {
if (this.isMatch(uri)) {
Logger.info(`Created: ${uri.path}`);
this.onDidCreateEmitter.fire(uri);
}
}),
watcher.onDidChange(uri => {
if (this.isMatch(uri)) {
Logger.info(`Updated: ${uri.path}`);
this.onDidChangeEmitter.fire(uri);
}
}),
watcher.onDidDelete(uri => {
if (this.isMatch(uri)) {
Logger.info(`Deleted: ${uri.path}`);
this.onDidDeleteEmitter.fire(uri);
}
})
);
}
}
match(files: URI[]) {
const matches = micromatch(
files.map(f => f.fsPath),
this._includeGlobs,
{
ignore: this._ignoreGlobs,
nocase: true,
}
);
return matches.map(URI.file);
}
isMatch(uri: URI) {
return this.match([uri]).length > 0;
}
async listFiles() {
const files = (
await Promise.all(
this._folders.map(async folder => {
const res = await findAllFiles(folderPlusGlob(folder)('**/*'));
return res.map(URI.file);
})
)
).flat();
return this.match(files);
}
async read(uri: URI) {
return (await fs.promises.readFile(uri.fsPath)).toString();
}
dispose() {
this._disposables.forEach(d => d.dispose());
}
}
const folderPlusGlob = (folder: string) => (glob: string): string => {
if (folder.substr(-1) === '/') {
folder = folder.slice(0, -1);
}
if (glob.startsWith('/')) {
glob = glob.slice(1);
}
return `${folder}/${glob}`;
};

View File

@@ -1,16 +0,0 @@
import { isSome } from './core';
const HASHTAG_REGEX = /(^|[ ])#([\w_-]*[a-zA-Z][\w_-]*\b)/gm;
const WORD_REGEX = /(^|[ ])([\w_-]*[a-zA-Z][\w_-]*\b)/gm;
export const extractHashtags = (text: string): Set<string> => {
return isSome(text)
? new Set(Array.from(text.matchAll(HASHTAG_REGEX), m => m[2].trim()))
: new Set();
};
export const extractTagsFromProp = (prop: string | string[]): Set<string> => {
const text = Array.isArray(prop) ? prop.join(' ') : prop;
return isSome(text)
? new Set(Array.from(text.matchAll(WORD_REGEX)).map(m => m[2].trim()))
: new Set();
};

View File

@@ -1,102 +0,0 @@
import { posix } from 'path';
import GithubSlugger from 'github-slugger';
import { hash } from './core';
import { URI } from '../common/uri';
import { statSync } from 'fs';
export const uriToSlug = (noteUri: URI): string => {
return GithubSlugger.slug(posix.parse(noteUri.path).name);
};
export const nameToSlug = (noteName: string): string => {
return GithubSlugger.slug(noteName);
};
export const hashURI = (uri: URI): string => {
return hash(posix.normalize(uri.path));
};
export const computeRelativePath = (source: URI, target: URI): string => {
const relativePath = posix.relative(posix.dirname(source.path), target.path);
return relativePath;
};
export const getBasename = (uri: URI) => posix.parse(uri.path).name;
export const getDir = (uri: URI) => URI.file(posix.dirname(uri.path));
export const computeRelativeURI = (
reference: URI,
relativeSlug: string
): URI => {
// if no extension is provided, use the same extension as the source file
const slug =
posix.extname(relativeSlug) !== ''
? relativeSlug
: `${relativeSlug}${posix.extname(reference.path)}`;
return reference.with({
path: posix.join(posix.dirname(reference.path), slug),
});
};
/**
* Parses a URI from value, taking into consideration possible relative paths.
*
* @param reference the URI to use as reference in case value is a relative path
* @param value the value to parse for a URI
* @returns the URI from the given value. In case of a relative path, the URI will take into account
* the reference from which it is computed
*/
export const parseUri = (reference: URI, value: string): URI => {
let uri = URI.parse(value);
if (uri.scheme === 'file' && !value.startsWith('/')) {
const [path, fragment] = value.split('#');
uri = path.length > 0 ? computeRelativeURI(reference, path) : reference;
if (fragment) {
uri = uri.with({
fragment: fragment,
});
}
}
return uri;
};
export const placeholderUri = (key: string): URI => {
return URI.from({
scheme: 'placeholder',
path: key,
});
};
/**
* Uses a placeholder URI, and a reference directory, to generate
* the URI of the corresponding resource
*
* @param placeholderUri the placeholder URI
* @param basedir the dir to be used as reference
* @returns the target resource URI
*/
export const placeholderToResourceUri = (
basedir: URI,
placeholderUri: URI
): URI => {
const tokens = placeholderUri.path.split('/');
const path = tokens.slice(0, -1);
const filename = tokens.slice(-1);
return URI.joinPath(basedir, ...path, `${filename}.md`);
};
export const isPlaceholder = (uri: URI): boolean => {
return uri.scheme === 'placeholder';
};
export const isSameUri = (a: URI, b: URI) =>
a.authority === b.authority &&
a.scheme === b.scheme &&
a.path === b.path && // Note we don't use fsPath for sameness
a.fragment === b.fragment &&
a.query === b.query;
export const isMarkdownFile = (uri: URI): boolean => {
return uri.path.endsWith('md') && statSync(uri.fsPath).isFile();
};

View File

@@ -1,3 +0,0 @@
# Roam Document
[[Second Roam Document]]

View File

@@ -1 +0,0 @@
# Second Roam Document

View File

@@ -1,81 +0,0 @@
import path from 'path';
import { NoteLinkDefinition, Note, Attachment } from '../src/model/note';
import * as ranges from '../src/model/range';
import { URI } from '../src/common/uri';
import { Logger } from '../src/utils/log';
import { parseUri } from '../src/utils';
Logger.setLevel('error');
const position = ranges.create(0, 0, 0, 100);
const documentStart = position.start;
const documentEnd = position.end;
const eol = '\n';
/**
* Turns a string into a URI
* The goal of this function is to make sure we are consistent in the
* way we generate URIs (and therefore IDs) across the tests
*/
export const strToUri = URI.file;
export const createAttachment = (params: { uri: string }): Attachment => {
return {
uri: strToUri(params.uri),
type: 'attachment',
};
};
export const createTestNote = (params: {
uri: string;
title?: string;
definitions?: NoteLinkDefinition[];
links?: Array<{ slug: string } | { to: string }>;
text?: string;
root?: URI;
}): Note => {
const root = params.root ?? URI.file('/');
return {
uri: parseUri(root, params.uri),
type: 'note',
properties: {},
title: params.title ?? path.parse(strToUri(params.uri).path).base,
definitions: params.definitions ?? [],
tags: new Set(),
links: params.links
? params.links.map((link, index) => {
const range = ranges.create(
position.start.line + index,
position.start.character,
position.start.line + index,
position.end.character
);
return 'slug' in link
? {
type: 'wikilink',
slug: link.slug,
target: link.slug,
range: range,
text: 'link text',
}
: {
type: 'link',
target: link.to,
label: 'link text',
range: range,
};
})
: [],
source: {
eol: eol,
end: documentEnd,
contentStart: documentStart,
text: params.text ?? '',
},
};
};
describe('Test utils', () => {
it('are happy', () => {});
});

View File

@@ -1,72 +0,0 @@
import { createConfigFromObject } from '../src/config';
import { Logger } from '../src/utils/log';
import { URI } from '../src/common/uri';
import { FileDataStore } from '../src';
Logger.setLevel('error');
const testFolder = URI.joinPath(URI.file(__dirname), 'test-datastore');
function makeConfig(params: { include: string[]; ignore: string[] }) {
return createConfigFromObject(
[testFolder],
params.include,
params.ignore,
{}
);
}
describe('Datastore', () => {
it('defaults to including nothing and exclude nothing', async () => {
const ds = new FileDataStore(
makeConfig({
include: [],
ignore: [],
})
);
expect(await ds.listFiles()).toHaveLength(0);
});
it('returns only markdown files', async () => {
const ds = new FileDataStore(
makeConfig({
include: ['**/*'],
ignore: [],
})
);
const res = toStringSet(await ds.listFiles());
expect(res).toEqual(
makeAbsolute([
'/file-a.md',
'/info/file-b.md',
'/docs/file-in-nm.md',
'/info/docs/file-in-sub-nm.md',
])
);
});
it('supports excludes', async () => {
const ds = new FileDataStore(
makeConfig({
include: ['**/*'],
ignore: ['**/docs/**'],
})
);
const res = toStringSet(await ds.listFiles());
expect(res).toEqual(makeAbsolute(['/file-a.md', '/info/file-b.md']));
});
});
function toStringSet(uris: URI[]) {
return new Set(uris.map(uri => uri.path.toLocaleLowerCase()));
}
function makeAbsolute(files: string[]) {
return new Set(
files.map(f =>
URI.joinPath(testFolder, f)
.path.toLocaleLowerCase()
.replace(/\\/g, '/')
)
);
}

View File

@@ -1,111 +0,0 @@
import * as path from 'path';
import { generateLinkReferences } from '../../src/janitor';
import { bootstrap } from '../../src/bootstrap';
import { createConfigFromFolders } from '../../src/config';
import { Note, ranges } from '../../src';
import { FileDataStore } from '../../src/services/datastore';
import { Logger } from '../../src/utils/log';
import { URI } from '../../src/common/uri';
import { FoamWorkspace } from '../../src/model/workspace';
import { getBasename } from '../../src/utils/uri';
Logger.setLevel('error');
describe('generateLinkReferences', () => {
let _workspace: FoamWorkspace;
const findBySlug = (slug: string): Note => {
return _workspace.list().find(res => getBasename(res.uri) === slug) as Note;
};
beforeAll(async () => {
const config = createConfigFromFolders([
URI.file(path.join(__dirname, '..', '__scaffold__')),
]);
_workspace = await bootstrap(config, new FileDataStore(config)).then(
foam => foam.workspace
);
});
it('initialised test graph correctly', () => {
expect(_workspace.list().length).toEqual(6);
});
it('should add link references to a file that does not have them', () => {
const note = findBySlug('index');
const expected = {
newText: textForNote(
note,
`
[//begin]: # "Autogenerated link references for markdown compatibility"
[first-document]: first-document "First Document"
[second-document]: second-document "Second Document"
[file-without-title]: file-without-title "file-without-title"
[//end]: # "Autogenerated link references"`
),
range: ranges.create(9, 0, 9, 0),
};
const actual = generateLinkReferences(note, _workspace, false);
expect(actual!.range.start).toEqual(expected.range.start);
expect(actual!.range.end).toEqual(expected.range.end);
expect(actual!.newText).toEqual(expected.newText);
});
it('should remove link definitions from a file that has them, if no links are present', () => {
const note = findBySlug('second-document');
const expected = {
newText: '',
range: ranges.create(6, 0, 8, 42),
};
const actual = generateLinkReferences(note, _workspace, false);
expect(actual!.range.start).toEqual(expected.range.start);
expect(actual!.range.end).toEqual(expected.range.end);
expect(actual!.newText).toEqual(expected.newText);
});
it('should update link definitions if they are present but changed', () => {
const note = findBySlug('first-document');
const expected = {
newText: textForNote(
note,
`[//begin]: # "Autogenerated link references for markdown compatibility"
[file-without-title]: file-without-title "file-without-title"
[//end]: # "Autogenerated link references"`
),
range: ranges.create(8, 0, 10, 42),
};
const actual = generateLinkReferences(note, _workspace, false);
expect(actual!.range.start).toEqual(expected.range.start);
expect(actual!.range.end).toEqual(expected.range.end);
expect(actual!.newText).toEqual(expected.newText);
});
it('should not cause any changes if link reference definitions were up to date', () => {
const note = findBySlug('third-document');
const expected = null;
const actual = generateLinkReferences(note, _workspace, false);
expect(actual).toEqual(expected);
});
});
/**
* Will adjust a text line separator to match
* what is used by the note
* Necessary when running tests on windows
*
* @param note the note we are adjusting for
* @param text starting text, using a \n line separator
*/
function textForNote(note: Note, text: string): string {
return text.split('\n').join(note.source.eol);
}

View File

@@ -1,63 +0,0 @@
import path from 'path';
import { loadPlugins } from '../src/plugins';
import { createMarkdownParser } from '../src/markdown-provider';
import { FoamConfig, createConfigFromObject } from '../src/config';
import { URI } from '../src/common/uri';
import { Logger } from '../src/utils/log';
Logger.setLevel('error');
const config: FoamConfig = createConfigFromObject([], [], [], {
experimental: {
localPlugins: {
enabled: true,
pluginFolders: [path.join(__dirname, 'test-plugin')],
},
},
});
describe('Foam plugins', () => {
it('will not load if feature is not explicitly enabled', async () => {
let plugins = await loadPlugins(createConfigFromObject([], [], [], {}));
expect(plugins.length).toEqual(0);
plugins = await loadPlugins(
createConfigFromObject([], [], [], {
experimental: {
localPlugins: {},
},
})
);
expect(plugins.length).toEqual(0);
plugins = await loadPlugins(
createConfigFromObject([], [], [], {
experimental: {
localPlugins: {
enabled: false,
},
},
})
);
expect(plugins.length).toEqual(0);
});
it('can load', async () => {
const plugins = await loadPlugins(config);
expect(plugins.length).toEqual(1);
expect(plugins[0].name).toEqual('Test Plugin');
});
it('supports parser extension', async () => {
const plugins = await loadPlugins(config);
const parserPlugin = plugins[0].parser;
expect(parserPlugin).not.toBeUndefined();
const parser = createMarkdownParser([parserPlugin!]);
const note = parser.parse(
URI.file('/path/to/a'),
`
# This is a note with header
and some content`
);
expect(note.properties.hasHeading).toBeTruthy();
});
});

View File

@@ -1,20 +0,0 @@
const middleware = next => ({
setNote: note => {
note.properties['injectedByMiddleware'] = true;
return next.setNote(note);
},
});
const parser = {
visit: (node, note) => {
if (node.type === 'heading') {
note.properties.hasHeading = true;
}
},
};
module.exports = {
name: 'Test Plugin',
graphMiddleware: middleware,
parser: parser,
};

View File

@@ -1,118 +0,0 @@
import {
uriToSlug,
nameToSlug,
hashURI,
computeRelativeURI,
extractHashtags,
parseUri,
} from '../src/utils';
import { URI } from '../src/common/uri';
import { Logger } from '../src/utils/log';
Logger.setLevel('error');
describe('URI utils', () => {
it('supports various cases', () => {
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'
);
});
it('converts a name to a slug', () => {
expect(nameToSlug('this.has.dots')).toEqual('thishasdots');
expect(nameToSlug('title')).toEqual('title');
expect(nameToSlug('this is a title')).toEqual('this-is-a-title');
expect(nameToSlug('this is a title/slug')).toEqual('this-is-a-titleslug');
});
it('normalizes URI before hashing', () => {
expect(hashURI(URI.file('/this/is/a/path.md'))).toEqual(
hashURI(URI.file('/this/has/../is/a/path.md'))
);
expect(hashURI(URI.file('this/is/a/path.md'))).toEqual(
hashURI(URI.file('this/has/../is/a/path.md'))
);
});
it('computes a relative uri using a slug', () => {
expect(computeRelativeURI(URI.file('/my/file.md'), '../hello.md')).toEqual(
URI.file('/hello.md')
);
expect(computeRelativeURI(URI.file('/my/file.md'), '../hello')).toEqual(
URI.file('/hello.md')
);
expect(
computeRelativeURI(URI.file('/my/file.markdown'), '../hello')
).toEqual(URI.file('/hello.markdown'));
});
describe('URI parsing', () => {
const base = URI.file('/path/to/file.md');
test.each([
['https://www.google.com', URI.parse('https://www.google.com')],
['/path/to/a/file.md', URI.file('/path/to/a/file.md')],
['../relative/file.md', URI.file('/path/relative/file.md')],
['#section', base.with({ fragment: 'section' })],
[
'../relative/file.md#section',
URI.parse('file:/path/relative/file.md#section'),
],
])('URI Parsing (%s) - %s', (input, exp) => {
const result = parseUri(base, input);
expect(result.scheme).toEqual(exp.scheme);
expect(result.authority).toEqual(exp.authority);
expect(result.path).toEqual(exp.path);
expect(result.query).toEqual(exp.query);
expect(result.fragment).toEqual(exp.fragment);
});
});
});
describe('hashtag extraction', () => {
it('works with simple strings', () => {
expect(extractHashtags('hello #world on #this planet')).toEqual(
new Set(['world', 'this'])
);
});
it('works with tags at beginning or end of text', () => {
expect(extractHashtags('#hello world on this #planet')).toEqual(
new Set(['hello', 'planet'])
);
});
it('supports _ and -', () => {
expect(extractHashtags('#hello-world on #this_planet')).toEqual(
new Set(['hello-world', 'this_planet'])
);
});
it('ignores tags that only have numbers in text', () => {
expect(
extractHashtags('this #123 tag should be ignore, but not #123four')
).toEqual(new Set(['123four']));
});
it('ignores hashes in plain text urls and links', () => {
expect(
extractHashtags(`
test text with url https://site.com/#section1 https://site.com/home#section2 and
https://site.com/home/#section3a
[link](https://site.com/#section4) with [link2](https://site.com/home#section5) #control
hello world
`)
).toEqual(new Set(['control']));
});
it('ignores hashes in links to sections', () => {
expect(
extractHashtags(`
this is a wikilink to [[#section1]] in the file and a [[link#section2]] in another
this is a [link](#section3) to a section
`)
).toEqual(new Set());
});
});

View File

@@ -1,6 +0,0 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "ESNext"
}
}

View File

@@ -1,29 +0,0 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"baseUrl": "src",
"composite": true,
"esModuleInterop": true,
"importHelpers": true,
"downlevelIteration": true,
// commonjs module format is used so that the incremental
// tsc build-mode ran during development can replace individual
// files (as opposed to generate the .cjs.development.js bundle.
//
// this is overridden in tsconfig.build.json for distribution
"module": "commonjs",
"moduleResolution": "node",
"outDir": "dist",
"rootDir": "./src",
"sourceMap": true,
"strict": true,
"lib": [
"ES2019", "es2020.string"
]
},
"include": [
"src",
"types"
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,177 @@ 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.15.4] - 2021-11-09
Fixes and Improvements:
- Detached Foam URI from VS Code URI. This should improve several path related issues in Windows. Given how core this change is, the release is just about this refactoring to easily detect possible side effects.
## [0.15.3] - 2021-11-08
Fixes and Improvements:
- Avoid delaying decorations on editor switch (#811 - thanks @memeplex)
- Fix preview issue when embedding a note and using reference definitions (#808 - thanks @pderaaij)
## [0.15.2] - 2021-10-27
Features:
- Added `FOAM_DATE_*` template variables (#781)
Fixes and Improvements:
- Dataviz: apply note type color to filter item label
- Dataviz: optimized rendering of graph to reduce load on CPU (#795)
- Preview: improved tag highlight in preview (#785 - thanks @pderaaij)
- Better handling of link reference definition (#786 - thanks @pderaaij)
- Link decorations are now enabled by default (can be turned off in settings)
## [0.15.1] - 2021-10-21
Fixes and Improvements:
- Improved filtering controls for graph (#782)
- Link Hover: Include other connected notes to link target
## [0.15.0] - 2021-10-04
Features:
- Preview on hover for wikilinks (#728 - thanks @JonasSprenger)
- Added tags and controls to graph dataviz (#737 - thanks @dannysemi)
Fixes and Improvements:
- Improved tags parsing (#708 - thanks @pderaaij)
- Fixed support for resources named like JS Object methods (#729 - thanks @JonasSprenger)
## [0.14.2] - 2021-07-24
Features:
- Autocompletion for tags (#708 - thanks @pderaaij)
- Use templates for new note created from wikilink (#712 - thanks @movermeyer)
Fixes and Improvements:
- Improved performance of initial file loading (#730 - thanks @pderaaij)
## [0.14.1] - 2021-07-14
Fixes and Improvements:
- Fixed NPE that would cause markdown preview to render incorrectly (#718 - thanks @pderaaij)
## [0.14.0] - 2021-07-13
Features:
- Create new note from selection (#666 - thanks @pderaaij)
- Use templates for daily notes (#700 - thanks @movermeyer)
Fixes and Improvements:
- Fixed for wikilink aliases in tables (#697 - thanks @pderaaij)
- Fixed link definition generation in presence of aliased wikilinks (#698 - thanks @pderaaij)
- Fixed template insertion of selected text (#701 - thanks @movermeyer)
- Fixed preview navigation (#710 - thanks @pderaaij)
## [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:
- Fixed #667, incorrect resolution of foam-core library
Internal:
- 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
Fixes and Improvements:
- Fixed #667, incorrect resolution of foam-core library
## [0.13.5] - 2021-06-05
Fixes and Improvements:
- Improved support for nested tags (#661 - thanks @pderaaij)
- Allow YAML metadata in templates (#655 - thanks @movermeyer)
- Fixed template exclusion globs (#665)
## [0.13.4] - 2021-05-26
Fixes and Improvements:
- Added support for nested tags (#643 - thanks @pderaaij)
- Improved the flow of creating note from template (#645 - thanks @movermeyer)
- Fixed handling of title property in YAML (#647 - thanks @pderaaij and #546)
Internal:
- Updated various dependencies
## [0.13.3] - 2021-05-09
Fixes and Improvements:
- Improved Foam template variables resolution: unknown variables are now ignored (#622 - thanks @movermeyer)
- Fixed file matching in MarkdownProvider (#617)
- Fixed cancelling `Foam: Create New Note` and `Foam: Create New Note From Template` behavior (#623 - thanks @movermeyer)
## [0.13.2] - 2021-05-06
Fixes and Improvements:
- Fixed wikilink completion bug (#592 - thanks @RobinKing)
- Added support for stylable tags (#598 - thanks @Barabazs)
- Added "Create new note" command (#601 - thanks @movermeyer)
- Fixed navigation from placeholder and orphan panel (#600)
Internal:
- Refactored data model representation of resources: `Resource` (#593)
## [0.13.1] - 2021-04-21
Fixes and Improvements:
- fixed bug in Windows when running `Open Daily Note` command (#591 - Thanks @RobinKing)
## [0.13.0] - 2021-04-19
Features:
- Wikilink completion (#554)
Fixes and Improvements:
- fixed link navigation on path with spaces (#542)
- support for Chinese characters in tags (#567 - thanks @RobinKing)
- added support for `FOAM_TITLE` in templates (#549 - thanks @movermeyer)
- added configuration to enable/disable link navigation (#584)
## [0.12.1] - 2021-04-05
Fixes and Improvements:
- Link decorations are now optional (#558)
- Improved UX when creating notes from templates (#550 - thanks @movermeyer)
## [0.12.0] - 2021-03-22
Features:

View File

@@ -5,9 +5,7 @@
[![Installs](https://img.shields.io/visual-studio-marketplace/i/foam.foam-vscode)](https://marketplace.visualstudio.com/items?itemName=foam.foam-vscode)
[![Ratings](https://img.shields.io/visual-studio-marketplace/r/foam.foam-vscode)](https://marketplace.visualstudio.com/items?itemName=foam.foam-vscode)
> ⚠️ This is an early stage software. Use at your own peril.
> You can join the Foam Community on the [Foam Discord](https://foambubble.github.io/join-discord/e)
[Foam](https://foambubble.github.io/foam) is a note-taking tool that lives within VsCode, which means you can pair it with your favorite extensions for a great editing experience.
@@ -30,8 +28,8 @@ You really, _really_, **really** should read [Foam documentation](https://foambu
## Features
- Connect your notes using [`[[wiki-links]]`](https://foambubble.github.io/foam/features/backlinking)
- Create markdown [references](https://foambubble.github.io/foam/features/link-reference-definitions) for `[[wiki-links]]`, to use your notes in a non-foam workspace
- Connect your notes using [`[[wikilinks]]`](https://foambubble.github.io/foam/features/backlinking)
- Create markdown [references](https://foambubble.github.io/foam/features/link-reference-definitions) for `[[wikilinks]]`, to use your notes in a non-foam workspace
- See how your notes are connected via a [graph](https://foambubble.github.io/foam/features/graph-visualisation) with the `Foam: Show Graph` command
- Tag your notes and navigate them with the [Tag Explorer](https://foambubble.github.io/foam/features/tags)
- Make your notes navigable both in GitHub UI as well as GitHub Pages

View File

@@ -8,11 +8,11 @@
"type": "git"
},
"homepage": "https://github.com/foambubble/foam",
"version": "0.12.0",
"version": "0.15.4",
"license": "MIT",
"publisher": "foam",
"engines": {
"vscode": "^1.47.1"
"vscode": "^1.61.0"
},
"icon": "icon/FOAM_ICON_256.png",
"categories": [
@@ -28,7 +28,8 @@
"onCommand:foam-vscode.copy-without-brackets",
"onCommand:foam-vscode.show-graph",
"onCommand:foam-vscode.create-new-template",
"onCommand:foam-vscode.create-note-from-template"
"onCommand:foam-vscode.create-note-from-template",
"onCommand:foam-vscode.create-note-from-default-template"
],
"main": "./out/extension.js",
"contributes": {
@@ -161,6 +162,10 @@
"command": "foam-vscode.create-note-from-template",
"title": "Foam: Create New Note From Template"
},
{
"command": "foam-vscode.create-note-from-default-template",
"title": "Foam: Create New Note"
},
{
"command": "foam-vscode.open-resource",
"title": "Foam: Open Resource"
@@ -230,21 +235,33 @@
"Disable wikilink definitions generation"
]
},
"foam.links.navigation.enable": {
"description": "Enable navigation through links",
"type": "boolean",
"default": true
},
"foam.links.hover.enable": {
"description": "Enable displaying note content on hover links",
"type": "boolean",
"default": true
},
"foam.decorations.links.enable": {
"description": "Enable decorations for links",
"type": "boolean",
"default": true
},
"foam.openDailyNote.onStartup": {
"type": "boolean",
"scope": "resource",
"default": false
},
"foam.openDailyNote.fileExtension": {
"type": "string",
"scope": "resource",
"default": "md"
},
"foam.openDailyNote.filenameFormat": {
"type": "string",
"default": "isoDate",
"markdownDescription": "Specifies how the daily note filename is formatted. See the [dateformat docs](https://www.npmjs.com/package/dateformat) for valid formats",
"scope": "resource"
"markdownDescription": "Specifies how the daily note filename is formatted. See the [dateformat docs](https://www.npmjs.com/package/dateformat) for valid formats"
},
"foam.openDailyNote.titleFormat": {
"type": [
@@ -252,8 +269,7 @@
"null"
],
"default": null,
"markdownDescription": "Specifies how the daily note title is formatted. Will default to the filename format if set to null. See the [dateformat docs](https://www.npmjs.com/package/dateformat) for valid formats",
"scope": "resource"
"markdownDescription": "Specifies how the daily note title is formatted. Will default to the filename format if set to null. See the [dateformat docs](https://www.npmjs.com/package/dateformat) for valid formats"
},
"foam.openDailyNote.directory": {
"type": [
@@ -268,8 +284,7 @@
"array"
],
"default": [],
"markdownDescription": "Specifies the list of glob patterns that will be excluded from the orphans report. To ignore the all the content of a given folder, use `**<folderName>/**/*`",
"scope": "resource"
"markdownDescription": "Specifies the list of glob patterns that will be excluded from the orphans report. To ignore the all the content of a given folder, use `**<folderName>/**/*`"
},
"foam.orphans.groupBy": {
"type": [
@@ -284,16 +299,14 @@
"Group by folder"
],
"default": "folder",
"markdownDescription": "Group orphans report entries by.",
"scope": "resource"
"markdownDescription": "Group orphans report entries by."
},
"foam.placeholders.exclude": {
"type": [
"array"
],
"default": [],
"markdownDescription": "Specifies the list of glob patterns that will be excluded from the placeholders report. To ignore the all the content of a given folder, use `**<folderName>/**/*`",
"scope": "resource"
"markdownDescription": "Specifies the list of glob patterns that will be excluded from the placeholders report. To ignore the all the content of a given folder, use `**<folderName>/**/*`"
},
"foam.placeholders.groupBy": {
"type": [
@@ -308,8 +321,7 @@
"Group by folder"
],
"default": "folder",
"markdownDescription": "Group blank note report entries by.",
"scope": "resource"
"markdownDescription": "Group blank note report entries by."
},
"foam.dateSnippets.afterCompletion": {
"type": "string",
@@ -349,9 +361,11 @@
"build": "tsc -p ./",
"pretest": "yarn build",
"test": "node ./out/test/run-tests.js",
"lint": "tsdx lint",
"test:unit": "node ./out/test/run-tests.js --unit",
"test:e2e": "node ./out/test/run-tests.js --e2e",
"lint": "tsdx lint src",
"clean": "rimraf out",
"watch": "tsc --build ./tsconfig.json ../foam-core/tsconfig.json --watch",
"watch": "tsc --build ./tsconfig.json --watch",
"vscode:start-debugging": "yarn clean && yarn watch",
"vscode:prepublish": "yarn npm-install && yarn run build",
"npm-install": "rimraf node_modules && npm i",
@@ -364,34 +378,54 @@
},
"devDependencies": {
"@babel/core": "^7.11.0",
"@babel/plugin-transform-runtime": "^7.10.4",
"@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",
"@types/micromatch": "^4.0.1",
"@types/node": "^13.11.0",
"@types/picomatch": "^2.2.1",
"@types/remove-markdown": "^0.1.1",
"@types/vscode": "^1.47.1",
"@types/vscode": "^1.61.0",
"@typescript-eslint/eslint-plugin": "^2.30.0",
"@typescript-eslint/parser": "^2.30.0",
"babel-jest": "^26.2.2",
"eslint": "^6.8.0",
"glob": "^7.1.6",
"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",
"ts-jest": "^26.4.4",
"typescript": "^3.8.3",
"vscode-test": "^1.3.0"
"tsdx": "^0.13.2",
"tslib": "^2.0.0",
"typescript": "^3.9.5",
"vscode-test": "^1.6.1"
},
"dependencies": {
"dateformat": "^3.0.3",
"foam-core": "^0.12.0",
"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",
"markdown-it-regex": "^0.2.0",
"micromatch": "^4.0.2",
"remove-markdown": "^0.3.0"
"remark-frontmatter": "^2.0.0",
"remark-parse": "^8.0.2",
"remark-wiki-link": "^0.0.4",
"remove-markdown": "^0.3.0",
"replace-ext": "^2.0.0",
"title-case": "^3.0.2",
"unified": "^9.0.0",
"unist-util-visit": "^2.0.2",
"yaml": "^1.10.0"
}
}
}

View File

@@ -0,0 +1,36 @@
{
"rules": {
"no-restricted-imports": [
"error",
{
"name": "vscode",
"message": "Core submodule must not depend on VS Code."
}
]
// Ideally we would also prevent the core module from depending on other modules
// but I have been struggling to get it to work.
// For future reference, below are some configurations I think should achieve this
// (but I couldn't manage to get working).
//
// "import/no-internal-modules": [
// "error",
// {
// "allow": ["./src/core"]
// }
// ]
// "import/no-restricted-paths": [
// "error",
// {
// "zones": [
// {
// "target": "./src/core",
// "from": "./src/(!core)",
// "message": "Core module can't have outside dependencies."
// }
// ]
// }
// ]
// "import/no-relative-parent-imports": "error"
// note: https://github.com/import-js/eslint-plugin-import/issues/1610
}
}

Some files were not shown because too many files have changed in this diff Show More