* Added setting to automatically convert wikilinks into md links on insertion/completion
* Improved Position mock and added mock for `extensions` namespace
Fixes#1464
* Support for image embed parameters (e.g. ![[img.png|300|center]])
Resolves#1328
Examples:
![[image.png]] // Original
![[image.png|300]] // Width only → 300px
![[image.png|50%]] // Percentage → responsive
![[image.png|300x200]] // Width × height
![[image.png|20em]] // With units
![[image.png|300|center]] // With alignment
![[image.png|300|Alt text]] // With alt text
* Documentation for image styling
* Add support for title in image links (#1262)
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Tag Peek References:
- Users can now peek all references of a tag
Enhanced Tag Search:
- Created new "Foam: Search Tag" ('foam-vscode.search-tag') command for workspace tag search
- Added inline search action button that appears on hover over tag items in tag explorer
- Clicking search icon triggers VS Code's search panel with tag query
FoamTags to use Location instead of URIs
Implements support for searching note aliases using VS Code's "Go To Symbol in Workspace" command (Ctrl+T/Cmd+T).
Resolves#1461
- Complements VS Code's built-in markdown symbol support (doesn't add symbols for sections)
- On-the-fly computation without caching for simplicity (will review if performance becomes an issue)
- Subsequence query matching following VS Code recommendations
Resolves#1505
When using root-path relative links (e.g., `[text](/path/file.md)`),
Ctrl+clicking would create new notes instead of opening existing files.
This was caused by the markdown provider treating workspace-relative
paths as filesystem absolute paths.
**Changes:**
- Enhanced MarkdownResourceProvider to accept workspace roots context
- Updated link resolution logic to handle workspace-relative paths correctly
- Modified extension initialization to pass VS Code workspace folders
- Enhanced createTestWorkspace() utility to support workspace roots testing
**Behavior:**
- Links starting with `/` now resolve against workspace roots first
- Falls back to existing absolute path behavior when no workspace roots
- Supports multiple workspace scenarios and fragments
- Maintains full backward compatibility
- Adds FOAM_DATE_DAY_ISO to variable resolver
- Adds dedicated and integrated tests for FOAM_DATE_DAY_ISO
- Updates documentation to describe FOAM_DATE_DAY_ISO usage and behavior
* Added FOAM_CURRENT_DIR template variable
* Added /research-issue Claude command
* Added integration test to create note using FOAM_CURRENT_DIR
* Updated documentation
* fixed comment
* Fail FOAM_CURRENT_DIR resolution if no editor nor workspace is open
The issue was caused by inconsistent path resolution in NoteFactory.createNote. When templates specified absolute paths like filepath: '/2025-09-05.md', the system was:
1. Checking file existence using the raw template path (filesystem absolute)
2. Creating files using the workspace-resolved path (workspace relative)
This mismatch caused the existence check to fail, leading to template reapplication.
- Template objects
- Separation of template loading, processing and file creation
- Support both Markdown and JavaScript templates
- Somewhat secure VM sandbox for JavaScript template execution in trusted workspaces
- Main entry point for note creation is `create-note` command
- Maintain backward compatibility with existing API
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Added VS Code mock to turn e2e into unit/integration tests
* Provide fallback to editor directory when creating new note with relative path
* Added `clear` function to `FoamWorkspace`
* Fixed tests for dated notes by providing configuration defaults
* Using different workspace directory when resetting mock
* tweaked test suite configuration to manage vscode mock
* Tweaked test scripts to allow running specs in "unit" mode with mock vscode environment
* Marked spec files that can be run in unit mode
* Added testing documentation
* removed --stream flag
* updated @types/node to match engine's version
* Fixing open-resource tests
Given that the link object is at times a string and at times an object (couldn't replicate, so exact cause unknown, but in line with the types of `force-graph` API), adding a function to properly extract the ID from the object
* wikilink embed: fixed bug in resolution, and extracted getNoteContent function
Bug was due to missing base note when resolving links in `withLinksRelativeToWorkspaceRoot`.
Also updated link to be rendered in HTML as absolute
* Improved embed reporting when running in web mode
* Fixed test (by not preloading document selectors)
* Using nodemon for watch task
* Added documentation and generator pattern to support getting some data from multiple sources
* asAbsoluteUrl can now take URI or string
* Tweaked daily note computation
* Replacing URI.withFragment with generic URI.with
* Removed URI.file from non-testing code
* fixed asAbsoluteUri
* Various tweaks and fixes
* Fixed create-note command
* Try and add in support for quarto wikilink autocomplete as in https://github.com/MilesMcBain/foam
* Try and add in support for quarto wikilink autocomplete as in https://github.com/MilesMcBain/foam but make it general based on a new config in settings.json, "foam.supportedLanguages". That should allow for rmarkdown files as well.
* remove package-lock.json in favor of yarn.lock
* Improved URI handling for virtual FS
* Ensure virtual filesystem is accepted as mdSelector
---------
Co-authored-by: Paul de Raaij <paul@paulderaaij.nl>
See https://github.com/foambubble/foam/pull/1290 for context.
Major thanks to @pderaaij that did all the hard work here.
* using js-sha1 instead of node's crypto to compute sha1
* Using esbuild to bundle native and web extension (WIP)
* Added message regarding unsupported embeds in web extension
* support for graph webview in web extension
* add generate standalone note command
* fix embeded wikilinks
* refactor convertLinksFormat function & add 4 user command interfaces
* change user interface
* modify createUpdateLinkEdit to accomplish convert
* only images can be embedded
* keey filename when using in page anchor
* give a default value to alias in link format combination branch
* add tests to createUpdateLinkEdit about changint links' type and isEmbed
* get target from getIdentifier
---------
Co-authored-by: Riccardo <code@riccardoferretti.com>
* Update readme.md to include code of conduct
lack of code of conduct that was in the previous version of foam _1
* added the Contribution Guide
this has a link to their Contribution Guide that is already on the foams website.
* Update readme.md presentation
added See the before the contribution guide and code of conduct links to make it more professional
* Update readme.md
---------
Co-authored-by: Riccardo <code@riccardoferretti.com>
* Introduced Location
* Passing a reference to the source link to the create-note command
Also
* Added withTiming fn for performance logging
* Added extra test to check incoming wikilink with sections
* Tweaked creation of vscode URI to also support raw objects
* Added encoding to handle special characters when wikilink definitions are generated
* Added tests for wikilinks encoding and updated previous tests to support encoded links
* extension descriptions now reflect .vscode dir
including that image pasting is now supported natively
* Markdown AiO is still recommended
---------
Co-authored-by: Daniel Carosone <dan@geek.com.au>
* Added expand all util function
* Added expand-all command for notes explorer
* Added expand-all command for placeholder tree view
* Added expand-all in tags explorer
* Added id field to tree items to make `reveal` work for all items
* Refactor note embedding to be extensible
* Prepare new setting to replace preview.embedNoteInContainer
* Fix wikilink-embed e2e tests
* Improve readability
* Set embedNoteInContainer to null in e2e tests to more closely mimic live state
* Updated FolderTreeProvider to allow for values at any level of the tree
* Added utility method "walk" and passing node to createValueTreeItem
* Moved tag explorer to use FolderTreeProvider
* Added path in node info
* Added commands for showing tags in workspace or current file only
* Added support for grouping or flattening tags hierarchy
* Moved e2e test cleanup in the suite so that it also works when running the tests from VS Code debug task
* Added flag for registering commands in tags-explorer (needed for testing :( )
* Update Jest to v29
* Add stream to workspace test
Without `--stream` in the workspace package, the command ends
successfully without correctly running the tests.
* Added multiple extension support for markdown provider
* Added default extension support
* Injecting extensions params to FoamWorkspace and MarkdownProvider (to avoid dependencies on non-core code)
* Inject extensions to attachment provider
* Introduced FOAM_TITLE_SAFE, which is the FOAM_TITLE variable with all the invalid path characters replaced by '-'
* (out of scope) In notes explorer show item description only when name is different from note title
* Renamed commands and labels in connections panel
* renamed backlinks.ts -> connections.ts
* (out of scope) In notes explorer show item description only when name is different from note title
* Turning backlinks panel to connections panel
* Added support for filter commands
* Fixed broken imports that were driving tests nuts
* Do not register connections.* commands during test
* Refactor: improved generate link references code
* Cleaned up update-wikilink module
* update-wikilink command uses janitor code
* Moved NoteLinkDefinition code in own class, and fixed duplication error
* Renamed command
* Testing on linux only...while I figure out the issue with the other systems
* Simplified feature activation API
* Moved tree view util modules and added comments to classes
* Removed deprecated command foam-vscode.create-note-from-default-template
* Added notes explorer
* Fixed line reference in range tree items
Thanks to Wikilens extensions for the high level inspiration (and the choice for the backlink tree item icon, as I find it just perfect)
* Addresses #1184
Currently tag completion only works in the front matter if you type a `#`
character. Adding the suggested tag will then mark the tag as a comment
```markdown
---
tags: #foo #bar
---
```
Update the tag completion provider to recognize if we are in the
front-matter, by using adding two functions to utils.ts. Because the
tag completion intellisense must be summoned with either the `#`
character or the keybinding (typically `ctrl+space`), allow
for 2 outcomes
1. if the tag is prefixed in the front matter with a `#`, remove it when
substituting the tag.
2. If `ctrl-space` is used, recognize we are on the `tags: ` line and
allow for non-`#` prefaced words.
The tag provider only works on the `tags: ` within the `tags: ` key of
the frontmatter. For example
```markdown
---
title: A title
tags:
- foo
- bar
- |
```
(where `|` is the cursor) will provide suggestions for tags.
Outside the `tags:` element, suggestions will not be provided.
```markdown
---
title: A title
tags:
- foo
- bar
dates:
- 2023-01-1
- |
```
* Refactor into functions for front matter & content
Refactor the main provider method into two
sub-functions, one for front matter, one for
regular content. Add helper functions to generate
the `CompletionItems` and to find the start & end
indices of the last match to `#{tag}`.
* Show note block in panels on hover preview
* Show tag references within tag explorer
* Improved structure of view related commands
* Refactored grouped resources tree data provider and added support for placeholders filter
- Consolidated the naming of the accessory commands
- Consolidated the management of the state/context related to grouping
- Removed group-by config, simply restore the last used setting
- Added filter to only show the placeholders related to the open file
* Refreshing placeholders when changing editor and filtering by active document
* Allow for `#` alone to trigger tag completion
In #1183, I reused [HASHTAG_REGEX](83a90177b9/packages/foam-vscode/src/core/utils/hashtags.ts (L2-L3))
to validate the tag line when the `CompletionProvider` was triggered.
I wanted to prevent this:
```markdown
# This is a Markdown header
```
but using the `HASHTAG_REGEX` had the side effect of requiring an
_additional_ character to trigger the completion provider.
```markdown
1. #p <-- triggers completion
2. # <-- does not trigger
3. #_ (space) <-- does not trigger
```
both 1. and 2. should have triggered.
To fix, I use a slightly different regex that uses a negative lookahead
to ensure that the `#` is not followed by a space. I also added spec
cases to cover this situation.
* Update regex for more robust detection of tags
Update the regex used for more robust detection of tags. Replace the
negative lookahead assertion `\s` with `[ \t]` (allow for `\n`), and
add `#` to the class so that `##` is ignored.
Attempted to add the negation `^[0-9p{L}p{Emoji}p{N}-/]` to the
negative look ahead. This was to exclude items like `#$`, `#&` that
can't be tags. However my regex-fu was insufficient.
Instead, if the regex match is to a single `#`, ensure it is the
character to the left of the cursor. Example
`this is text #%|`
where the `|` represents the cursor. The `TAG_REGEX`
will match the `#` at index 13. However since the cursor is at 15, the
Completion provider will not run.
Update the tests to cover these situations and add them all to a sub-
`describe` block labeled by the bug issue number #1189
* Use regex groups to determine match position
For the case like `here is #my-tag and now # |`, where `|` is the cursor
position after a trailing space, the match on `#my-tag` would allow tag
completion at the cursor position.
Ensure that the last regexp match group covers up to the the cursor
position. This also handles the case of `#$` because the match will only
be `#`.
This commit fixes an issue in the note creation flow where a template is used. Before the fix, when a template is present, Foam would force an absolute path resolution instead of delegating that step to the note creation. After the fix this step is removed and the resolution is left to the note creation code
Instead of a generic `TAG_REGEX`, use the more specific `HASHTAG_REGEX` to identify a tag when launching tab completion.
Also add a new test case with the issue number in the test case description
* Added title param in create-note command
* Added utility functions for commands
* Use create-note command when dealing with placeholders
* Updated open-resource command to new pattern
* Pass workspace.isTrusted to createFilter
* Fixed bug when finding absolute paths in workspace without providing basedir
* open-resource command can also receive `uri` param to skip filtering step
* added tests
* added docs
* Updated typescript and vscode engine version to support workspace trust
* updates tsdx to dts, and updated a other deps too
* updated eslint configuration
* Updated node version
* Update lerna
* Updated github action configuration
* removed glob library
* Added note filter and a few tests
* Added expression for filters and trusted workspace support
* Consolidate `include` and `exclude` into `path` parameter
* Added documentation
* fixing some unmatched links, daily-note path note, start graphviz/tags/properties clarification
fixed links that didn't actually link to their target, add discussion about creating daily-notes in path based off date, then clarifying notes about styling graph viz and tags while enhancing the note properties descriptions by describing how properties are described and which properties are custom, which are foam-specific, and which are foam-template-specific
* add filter view, default variables to graphviz, and viewing tags in graphviz
graphviz: discuss filter view, add all changeable variables to graph style example, tags: describe viewing tags in the graphviz
* add small note about learning yaml
* last push fixing up some todos
* making recommended changes from PR request
* Added path util to resolve absolute path from multiple base directories
* Better support for multiple roots in include/ignore globs
* URI.asAbsolutePath to use path utils
* Lint
* Add a hover tooltip to placeholder links offering to create a new note from template
* Clicking the placeholder tooltip asks for template for new note
* Create new note from template using `CREATE_NOTE` command
* Update tests
* Added create-note command and refactored some template code
* Added tests
* Added uri resolution logic across multiple folders
* Deprecating create-note-from-default-template command, it is now replaced by the new and more flexible create-note command (which still has the same defaults)
* Reorganize docs folder; isolate dev docs and user docs; integrate foam-template docs
* Rename how-to to getting-started
* Fixup all references
* Fix contribution-guide.md
* Fix asset references
* Fix user/index.md
* Spelling is good.
Thanks @DrakeWhu
* Add note about how to wite docs for foam
Removed resource.source property:
* removed usage of resource.source.text
* removed usage of resource.source.eol
* removed usage of resource.source.contentStart
* removed usage of resource.source.end
* removed resource.source
Small change in provider set up:
* added IWatcher interface
* changed fs watcher set up
Commands refactoring:
* moved commands in own directory
* split one command per file
* added "update graph" command
* renamed date-snippet file (before it included a combination of commands and snippet completion)
Also some test cleanup:
* made tests about note renaming/sync more reliable
* improved clean up between tests
* improved reporting in test runs
* fixed exit on failure behavior to surface exit code to CI
* Added attachment provider
* distinguish attachment and image types
* Added support for embeding images/attachments
* Added setting to decide whether to show notes in container in preview panel
Remove references that are wiki links, they are not needed (because Foam will take care of the routing in the preview) and they cause the rendering of wiki links to be surrounded by square brackets.
* basic implementation of file rename support
* tweaks to various tests
* make lint happy again
* Improved reporting
* added setting related to file sync
* added documentation in readme
There was an issue with navigation that would cause multiple text editors to be opened for the same file.
Turns out the issue was related to the use of URIs that included the fragment component, as well as the interaction between the link provider and the definition provider.
This commit fixes the issue.
Fixes#941
Unfortunately there is no way to see which errors are being skipped, but at the same time it makes sense to not be strict and have a single file block a whole scan (especially because it could be a file Foam is not even interested in).
* create slugified title variable available in templates
* add test
* add FOAM_SLUG to documentation
* add github-slugger dependency
Co-authored-by: Brian DeVries <brian@brianjdevries.com>
* Add the snippet parsing code from VSCode
From 95be30b3ac
* Remove `override` keyword
This is a TypeScript 4.3 feature, but Foam is not there yet
* Use `SnippetParser` to find Foam variables
* Return `Variable` objects from `findFoamVariables`
* Make `SnippetParser` resolve async
* Implement a `VariableResolver`
* Add start/end positions to `Variable`s
* Substitute based on indices, not regex
* Remove limitation warning from docs
* Merge `FoamVariableResolver` and `Resolver`
* Remove `extraVariablesToResolve`
It was no longer being used for `FOAM_TITLE`, and `FOAM_SELECTED_TEXT` didn't need to have it set either, so long as it appeared in `givenValues`, which it does.
* Add name filter to `resolveVariables`
You cannot call `resolve` on a `Variable` without modifying it, even if your `VariableResolver` doesn't know how to resolve the `Variable`.
For example, a `Transform` with a default value will modify the `Varible`'s `children`, even if the `VariableResolver` does not resolve a value.
Instead, we add a name filter, so that we don't resolve any `Variable`s that aren't Foam variables.
* Return `undefined` when the `VariableResolver` cannot resolve a `Variable`
This is how a `VariableResolver` is supposed to behave in these cases.
* Move variable substitution into `TextmateSnippet`
That way, the Foam `VariableResolver` code doesn't need to keep track of the text, nor interact with the `Variable` `pos`/`endPos`.
* Added support for sections/subsections in `Resource`
* Added support for sections in navigation and definitions
* Section completion
* Diagnostics and quick actions for sections
* Added support for section embeds in preview
* Added reference to sections support in readme file
* Add support for sections in direct links
* Added support for sections in identifier computation
* Support for section wikilinks within same file
* Tweaks
* using different approach to store/look-up references in FoamWorkspace that also supports better wikilink matching
* added documentation for Foam wikilinks
* added changelog
* refactored note templates code
* more tests for "Create from template" commands
* inject resolver
* implemented feedback from PR #827 (Authored by @l2dy)
- introduce definition and references support
- changes links to only be used for placeholders
- simplifies configuration
Co-authored-by: Jonas Sprenger <sprengerjo@gmail.com>
* 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
* 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>
* 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
* Add the functionality to include notes in a note
* Add proposal of embedding
* Add tests for including notes
* Add documentation for inclusion feature
* 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
* 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>
* 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>
* 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>
* 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
* 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
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.
* 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_]
* 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
* Fix: Right links and formatting
* Docs: Run markdownlint to automatically fix minor formatting errors
* Style: Format with markdownlint and not prettier
* 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
* 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>
* 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>
* added uri utility method, and exposing uri module
* added utility methods
* renamed and enhanced open-placeholder-note command to support all resources
* support for links via document link provider and decorator
* use open resource command in tree data provider
* make open resource command unavailable in command palette
* using snippet for better UX when creating note from placeholder
* exposing parser as a Foam service
* consolidated "open resource" command code
* added tests for document links provider
* added caching of VS Code also for lint
Even if linting doesn't require the vscode part of the cache, we are not separating the two cases so that we only have one cache to maintain, and linting being a faster task (and a task that should fail less than tests) will update the cache more often, speeding up the run of the tests afterwards
* `FoamWorkspace.find` to return `null` when no reference is provided for relative path
* turning wikilinks into browsable links in markdown preview
* moved preview styles in css file and reorganized code in static folder
Static was previous used only for the dataviz graph. Now we have 2 subdirectories: dataviz for the graph, and preview for the markdown preview.
For now the css style is a bit of an overkill, but sets up the right foundation for further customization down the line.
* chore: explicitly disabling gitdoc extension, removing unnecessary async keyword
* fix: fixed test utility fn (and linter warning)
* test: added tests for preview link generation
* changed launch configuration to support both foam-core and foam-vscode packages
* Use URI throughout dated-notes
* Fix typos in comments
* Allow absolute paths in `openDailyNote.directory`
This allows users to press the `alt-d` shortcut to open the daily note
from any instance of VSCode, not just within the `foam-template` repo.
The even listener is called with `this` bound to undefined, which causes the refresh function in fail when it accesses the object methods/fields. wrapping it into an arrow function avoids the problem
* Create Blank Note Explorer View
Creates a new "Blank Note" explorer view which displays all notes that
contain only a title. When note.source.text.trim().split('\n').length
is equal to 1, a note is considered blank. This should mean that the
note contains only a title.
The UX experience is identical to that of the Orphan view. A user can
toggle between both the flat view and a nested view grouped by
directory.
* Cleaned up views and made them much more dynamic.
Instead of just copy and pasting the orphans view into blank notes,
I created a filtered notes provider, which behaves identically to the
old orphan/blank notes providers, but allows the caller to pass in the
"filter function" which will narrow down the list of notes in the view.
This also allows us to more easily unit test the filtering logic, and
only test the flatten / nested logic in one place. It also makes it so
that when we refactor the way one of these views works (e.g. adding the
markdown preview), we don't have to make changes to the other view.
* Fixed unit test that was failing in Windows.
* Combined placeholders and blank notes.
* Removed workspacesFsPaths and replaced with workspacesURIs
Co-authored-by: J.T. James <joel.james@myfuelmaster.com>
* improved resolution for direct links and wikilink with definition
* if the definition of a wikilink points to a non-existing file, create a placeholder for the full path instead
* if a link doesn't point to a valid resource, create a placeholder for the full path instead
* commented out test-data.js import in dataviz.html
* moved test to more appropriate group
* Combine steps
* Cancel if escape pressed in any step
* New template command
* Execute "create new template" when no templates found
* Provide inline documentation
* Add tests
* Add docs for the feature
Co-authored-by: Jonathan <jonny@mondago.com>
* improved delta logic in graph.js
fixes a bug that was due to using object.splice inside a forEach loop (sometimes stackoverflow is wrong - removing the element inside the loop will actually reduce the iterations and not all elements in the array will be visited!)
* various fixes to live update of workspace model + tests
* added tab size option in settings.json
* added workspace WIP
* workspace supports resources
* uri check more lenient (was causing bug by not recognizing some objects)
* added placeholder resource type
* consolidated code in FoamWorkspace and added more tests
* updated all modules to use FoamWorkspace
* fixed FoamWorkspace.getConnections function
when links or backlinks are not present it no longer adds `undefined` to the connection list
* fix in workspace handling of direct links
* consolidated id/name generation functions
* added test for wikilink resolution when several notes have same filename
* removed reference to graphMiddleware in foam-local-plugins doc
graph middleware won't be supported with the `FoamWorkspace`. Support for the markdown provider remains
* removed support for graph middleware, graphlib dependency, and old note-graph implementation
Running the tests with vscode 1.53.0 is causing issues in `suite.ts:23`, which is causing a stack overflow, possibly due to a recursive callback. Also see https://github.com/foambubble/foam/pull/479#issuecomment-774167127 .
It's unclear what's causing the issue, but forcing the version to 1.52.0 solves the problem.
To review, further investigate, and roll back this workaround.
* fix#442 - link to known-issues replaced
* formatted settings + enable format on save + improved jest config
* removed editorconfig in foam-cli
* formatted foam-vscode
* removed author in package.json files
* minor changes to readme files
* fixed husky pre-commit hook
* Add graph style to VSCode settings
* Update default to an empty object
* Add function to retrieve the graph style from the settings
* Implement the graph custom styling setting
The implementation makes use of the webview communication mechanism to
switch messages between the webview and the graph.
It works as follows:
- When the webview is loaded, it now sends a single request to VSCode,
the request asks VSCode for the graph style
- When VSCode answers with the style, the graph style is updated and
the webview loading process continues as normal.
The style change does not modify the API, in fact it makes use of the
shadiest programming tatic ever, *global variables* to remain
compatible.
The style object *currently* supports four base fields:
- background: string
- fontSize: int
- highlightedForeground: string
- node: object
- note: string
- nonExistingNote: string
- unknown: string
* Simplify null handling logic
* Remove debug logs
* Rename style setting
* Rename message style type
* Remove forgotten debug log
* Refactor the code to match model & action
* Add missing break
* Allow for dynamic style updates
* Fix the window loading bug
* Implement a permanent fix to the bug
* Replace `nonExistingNote` with `placeholder`
* Include the new graph style feature in the docs
* Remove unnecessary async
* Remove unused case
* support direct links
* added support for labels with formatting
* added documentation and removed lint warning
* ignore external links
* improved uri parsing
* filter links pointing to same note (e.g. sections within the note)
* check that note exists before navigating to it
* fixed compilation error
* added support for e2e vscode tests
* using github action that supports headless test run
* loading vscode test instance in empty dir to speed up bootstrap
* add windows-2019 to CI os matrix
* use actual URI object instead of strings to represent paths/uris
* added datastore tests
* chore: make Foam IDisposable
* fix(graph): Don't delete node for note on update
Doing so causes graphlib to delete the inbound links from other nodes so when this node is re-created it will be adrift by itself.
* Clear graph node's forward links on note update so they can be accurately rebuilt
* test(dataviz): Ensure updating a note does not clear its backlinks (tests #393)
* fix(dataviz): On note delete, set node to "no file" state if it is referenced by other notes
* test(dataviz): Ensure graph updates properly from note deletions
* reorganized and updated foam docs
* minor changes to vscode extension readme
* added 404 page and minor changes
Co-authored-by: Joe Previte <jjprevite@gmail.com>
Added API and events around note deletion
Improved github workflows, added logic to avoid duplicate runs in CI and merged build + test jobs
Added support for running workflows in multiple environments, commented window-2019 as test don't pass, but they will be fixed in another PR to avoid scope creep here.
* Improved logging
- using classes instead of functions (feels like it fits better the use case)
- using singleton global to not pass logging service around
* Added vscode logger, command to change level, and settings
* improved bootstrap logging
* build foam-core before running tests in github workflows
This repository is a [monorepo](https://en.wikipedia.org/wiki/Monorepo) managed by [Yarn Workspaces](https://classic.yarnpkg.com/en/docs/workspaces/).
- The [packages](packages/) directory contains all Foam core code packages
- The [docs](docs/) directory contains a Foam workspace that hosts the official [documentation site](https://foambubble.github.io/foam)
The foam starter template lives outside of this repository at [foambubble/foam-template](https://github.com/foambubble/foam-template).
See [Foam Contribution Guide](https://foambubble.github.io/foam/contribution-guide) on the rendered Foam workspace for more information on how to contribute to Foam.
description:Suggest an idea for the `Foam` project
body:
- type:markdown
attributes:
value:|
This issue form is for requesting features only!
If you want to report a bug, please use the [bug report](https://github.com/foambubble/foam/issues/new?assignees=&labels=&template=bug_report.yml) form.
- type:textarea
validations:
required:true
attributes:
label:Is your feature request related to a problem? Please describe.
description:A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
- type:textarea
validations:
required:true
attributes:
label:Describe the solution you'd like
description:A clear and concise description of what you want to happen.
placeholder:|
As a user, I expected ___ behavior but ___ ...
Ideal Steps I would like to see:
1. Go to '...'
2. Click on '....'
3. ....
- type:textarea
validations:
required:true
attributes:
label:Describe alternatives you've considered
description:A clear and concise description of any alternative solutions or features you've considered.
- type:textarea
attributes:
label:Screenshots or Videos
description:|
If applicable, add screenshots or a video to help explain your problem.
For more information on the supported file image/file types and the file size limits, please refer
to the following link: https://docs.github.com/en/github/writing-on-github/working-with-advanced-formatting/attaching-files
placeholder:|
You can drag your video or image files inside of this editor ↓
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Collaboration Principles
**Be honest and objective**: Evaluate all suggestions, ideas, and feedback on their technical merits. Don't be overly complimentary or sycophantic. If something doesn't make sense, doesn't align with best practices, or could be improved, say so directly and constructively. Technical accuracy and project quality take precedence over being agreeable.
## Project overview
Foam is a personal knowledge management and sharing system, built on Visual Studio Code and GitHub. It allows users to organize research, keep re-discoverable notes, write long-form content, and optionally publish it to the web. The main goals are to help users create relationships between thoughts and information, supporting practices like building a "Second Brain" or a "Zettelkasten". Foam is free, open-source, and extensible, giving users ownership and control over their information. The target audience includes individuals interested in personal knowledge management, note-taking, and content creation, particularly those familiar with VS Code and GitHub.
## Quick Commands
All the following commands are to be executed from the `packages/foam-vscode` directory
### Development
-`yarn install` - Install dependencies
-`yarn build` - Build all packages
-`yarn watch` - Watch mode for development
-`yarn clean` - Clean build outputs
-`yarn reset` - Full clean, install, and build
### Testing
-`yarn test` - Run all tests (unit + integration)
-`yarn test:unit` - Run unit tests (\*.test.ts files and the .spec.ts files marked a vscode-mock friendly)
-`yarn test:e2e` - Run only integration tests (\*.spec.ts files)
-`yarn lint` - Run linting
-`yarn test-reset-workspace` to clean test workspace
Unit tests run in Node.js environment using Jest
Integration tests require VS Code extension host
When running tests, do not provide additional parameters, they are ignored by the custom runner script. You cannot run just a test, you have to run the whole suite.
Unit tests are named `*.test.ts` and integration tests are `*.spec.ts`. These test files live alongside the code in the `src` directory. An integration test is one that has a direct or indirect dependency on `vscode` module.
There is a mock `vscode` module that can be used to run most integration tests without starting VS Code. Tests that can use this mock are start with the line `/* @unit-ready */`.
- If you are interested in a test inside a `*.test.ts` file, run `yarn test:unit` or inside a `*.spec.ts` file that starts with `/* @unit-ready */` run `yarn test:unit`
- If you are interested in a test inside a `*.spec.ts` file that does not include `/* @unit-ready */` run `yarn test`
While in development we mostly want to use `yarn test:unit`.
When multiple tests are failing, look at all of them, but only focus on fixing the first one. Once that is fixed, run the test suite again and repeat the process.
When writing tests keep mocking to a bare minimum. Code should be written in a way that is easily testable and if I/O is necessary, it should be done in appropriate temporary directories.
Never mock anything that is inside `packages/foam-vscode/src/core/`.
Use the utility functions from `test-utils.ts` and `test-utils-vscode.ts` and `test-datastore.ts`.
To improve readability of the tests, set up the test and tear it down within the test case (as opposed to use other functions like `beforeEach` unless it's much better to do it that way)
Never fix a test by adjusting the expectation if the expectation is correct, test must be fixed by addressing the issue with the code.
## Repository Structure
This is a monorepo using Yarn workspaces with the main VS Code extension in `packages/foam-vscode/`.
### Key Directories
-`packages/foam-vscode/src/core/` - Platform-agnostic business logic (NO vscode dependencies)
-`packages/foam-vscode/src/features/` - VS Code-specific features and UI
-`packages/foam-vscode/src/services/` - service implementations, might have VS Code dependency, but we try keep that to a minimum
-`packages/foam-vscode/src/test/` - Test utilities and mocks
-`docs/` - Documentation and user guides
### File Naming Patterns
Test files follow `*.test.ts` for unit tests and `*.spec.ts` for integration tests, living alongside the code in `src`. An integration test is one that has a direct or indirect dependency on `vscode` package.
### Important Constraint
Code in `packages/foam-vscode/src/core/` MUST NOT depend on the `vscode` library or any files outside the core directory. This maintains platform independence.
## Architecture Overview
### Core Abstractions
**FoamWorkspace** - Central repository managing all resources (notes, attachments)
- Uses reversed trie for efficient resource lookup
- Register VS Code commands, providers, and event handlers
- Access the Foam workspace when ready
- Extend markdown-it for preview rendering
### Testing Conventions
-`*.test.ts` - Unit tests using Jest
-`*.spec.ts` - Integration tests requiring VS Code extension host
- Tests live alongside source code in `src/`
- Test cases should be phrased in terms of aspects of the feature being tested (expected behaviors), as they serve both as validation of the code as well as documentation of what the expected behavior for the code is in different situations. They should include the happy paths and edge cases.
## Development Workflow
We build production code together. I handle implementation details while you guide architecture and catch complexity early.
When working on an issue, check if a `.agent/tasks/<issue-id>-<sanitized-title>.md` exists. If not, suggest whether we should start by doing a research on it (using the `/research-issue <issue-id>`) command.
Whenever we work together on a task, feel free to challenge my assumptions and ideas and be critical if useful.
## Core Workflow: Research → Plan → Implement → Validate
**Start every feature with:** "Let me research the codebase and create a plan before implementing."
1.**Research** - Understand existing patterns and architecture
2.**Plan** - Propose approach and verify with you
3.**Implement** - Build with tests and error handling
4.**Validate** - ALWAYS run formatters, linters, and tests after implementation
- Whenever working on a feature or issue, let's always come up with a plan first, then save it to a file called `/.agent/current-plan.md`, before getting started with code changes. Update this file as the work progresses.
- Let's use pure functions where possible to improve readability and testing.
### Adding New Features
1. Create feature in `src/features/` directory
2. Register feature in `src/features/index.ts`
3. Add tests (both unit and integration as needed)
4. Update configuration in `package.json` if needed
### Working on an issue
1. Get the issue information from github
2. Define a step by step plan for addressing the issue
3. Create tests for the feature
4. Starting from the first test case, implement the feature so the test passes
### Core Logic Changes
1. Modify code in `src/core/` (ensure no vscode dependencies)
2. Add comprehensive unit tests
3. Update integration tests in features that use the core logic
## Configuration
The extension uses VS Code's configuration system with the `foam.*` namespace.
You can find all the settings in `/packages/foam-vscode/package.json`
## Common Development Tasks
### Extending Core Functionality
When adding to `src/core/`:
- Keep platform-agnostic (no vscode imports)
- Add comprehensive unit tests
- Consider impact on graph and workspace state
- Update relevant providers if needed
## Dependencies
- **Runtime**: VS Code API, markdown parsing, file watching
- **Development**: TypeScript, Jest, ESLint, esbuild
The extension supports both Node.js and browser environments via separate build targets.
## Documentation Guidelines
### User Documentation (`docs/user/`)
Documentation in `docs/user/` must be written for non-technical users. The goal is to help novice users quickly start using features, not to explain technical implementation details.
**Writing Guidelines:**
- **Target audience**: Assume users are new to Foam and may not be technical
- **Be concise**: Keep it short and to the point - every sentence must convey useful information
- **Avoid repetition**: Don't repeat the same concept in different words
- **Focus on "how to use"**: Show users what they can do and how to do it, not how it works internally
- **Balance brevity with clarity**: Users won't read verbose documentation, but they need enough information to succeed
- **Use examples**: Show practical use cases rather than abstract descriptions
- **Start with the most common use case**: Lead with what most users will want to do first
# GitHub CLI Integration
To interact with the github repo we will be using the `gh` command.
ALWAYS ask before performing a write operation on Github.
## Common Commands for Claude Code Integration
### Issues
```bash
# List all issues
gh issue list
# Filter issues by milestone
gh issue list --milestone "v1.0.0"
# Filter issues by assignee
gh issue list --assignee @me
gh issue list --assignee username
# Filter issues by label
gh issue list --label "bug"
gh issue list --label "enhancement,priority-high"
# Filter issues by state
gh issue list --state open
gh issue list --state closed
gh issue list --state all
# Combine filters
gh issue list --milestone "v1.0.0" --label "bug" --assignee @me
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**
- 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
- You can drag the backlinks pane to a different section in VS Code if you prefer. See: [[make-backlinks-more-prominent]]
- 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"
[make-backlinks-more-prominent]: make-backlinks-more-prominent.md "Make Backlinks More Prominent"
Head over to the [[contribution-guide]]. `CONTRIBUTING.md` file name is blocklisted on GitHub pages, and doesn't appear in the [rendered output](https://foambubble.github.io/foam).
[//begin]: # "Autogenerated link references for markdown compatibility"
> [[todo]] [[good-first-task]] This contribution guide itself could be improved 😅
Foam is open to contributions of any kind, including but not limited to code, documentation, ideas, and feedback. Here are some general tips on how to get started on contributing to Foam:
- Use Foam for yourself, figure out what could be improved.
- Check out [[roadmap]] to see what's already in the plans. I have thoughts about how to implement some of these, but open to ideas and code contributions!
- Read about our [[principles]] to understand Foam's philosophy and direction
- Read and act in accordance with our [[code-of-conduct]].
- Feel free to open [GitHub issues](https://github.com/foambubble/foam/issues) to give me feedback and ideas for new features.
- Foam code and documentation live in the monorepo at [foambubble/foam](https://github.com/foambubble/foam/)
- [/docs](https://github.com/foambubble/foam/docs): documentation and [[recipes]]
- [/packages/foam-vscode](https://github.com/foambubble/foam/tree/master/packages/foam-vscode): the core VSCode plugin
- [/packages/foam-core](https://github.com/foambubble/foam/tree/master/packages/foam-core): powers the core functionality in Foam across all platforms
- 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.
## Contributing to the VS Code Extension
If you're interested in contributing to the VS Code extension (aka `foam-vscode`), this guide will help you get things set up locally.
2. Install the necessary dependencies by running this command from the root:
`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:
`yarn workspace foam-core build`
4. 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.
5. 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). This is strictly not necessary, but the extension won't auto-run unless it's in a workspace with a `.vscode/foam.json` file.
6. 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]: tutorial-adding-a-new-command-to-the-vs-code-extension.md "Tutorial: Adding a New Command to the VS Code Extension"
- Write out a new `[[wiki-link]]` 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`
- Add a keyboard binding to make creating new notes easier.
- You shouldn't worry too much about categorising 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]: search-for-notes.md "Search for Notes"
Visual Studio Code allows you to use your own CSS in the Markdown preview tab.
## Instructions
Custom CSS for the Markdown preview can be implemented by using the `"markdown.styles": []` setting in `settings.json`. The stylesheets can either be https URLs or relative paths to local files in the current workspace.
For example, to load a stylesheet called `Style.css`, we can update `settings.json` with the following line:
Automatically create a Daily Note by executing the "Foam: Open Daily Note" command. If a Daily Note for today's date already exists, the command opens the existing note.

## Keyboard shortcut
The default keyboard shortcut for "Open Daily Note" is `alt`+`d`. This can be overridden using the [VS Code Keybindings editor](https://code.visualstudio.com/docs/getstarted/keybindings).
## Configuration
By default, Daily Notes will be created in a file called `yyyy-mm-dd.md` in the workspace root, with a heading `yyyy-mm-dd`.
These settings can be overridden in your workspace or global `.vscode/settings.json` file, using the [**dateformat** date masking syntax](https://github.com/felixge/node-dateformat#mask-options):
The above configuration would create a file `journal/note-2020-07-25.mdx`, with the heading `Journal Entry, Sunday, July 25`.
## Daily Note Templates
In the future, Foam may provide a functionality for specifying a template for new Daily Notes and other types of documents.
In the meantime, you can use [VS Code Snippets](https://code.visualstudio.com/docs/editor/userdefinedsnippets) for defining your own Daily Note template.
## Roam-style Automatic Daily Notes
In the future, Foam may provide an option for automatically opening your Daily Note when you open your Foam workspace.
If you want this behavior now, you can use the excellent [Auto Run Command](https://marketplace.visualstudio.com/items?itemName=gabrielgrinberg.auto-run-command#review-details) extension to run the "Open Daily Note" command upon entering a Foam workspace by specifying the following configuration in your `.vscode/settings.json`:
The best way to develop docs for the Foam repo is to directly open the `$foam-repo/docs/` as the root folder in a new vscode window.
This automatically configures vscode with the necessary settings enabled (like [[link-reference-definitions]]) to efficiently write this documentation.
## Organization
The Foam documentation is organized into two areas:
* User docs, located at `$foam-repo/docs/user/*`, which are copied in their entirety into `$foam-template-repo/docs`.
* Developer docs, located at `$foam-repo/docs/dev/*`
New user docs should be added to the User docs folder in the main Foam repo, then copied over to the Foam Template repo.
> [[todo]]: Automate this process. Idea: github action to open a PR on any change to `/docs/user`
[//begin]: # "Autogenerated link references for markdown compatibility"
The Foam prototype is built by assembling third-party extensions, which seems like a good strategy because
- It supports picking and mixing of tools and workflows
- Less code to write an maintain
- Less code to write and maintain
But there's also a bunch of roadmap items that are hard to implement this way, as the third party plugins don't do exactly what we want them to do (e.g. Markdown All In One is not compatible with [[referencing-notes-by-title]].
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.
[//begin]: # "Autogenerated link references for markdown compatibility"
[referencing-notes-by-title]: referencing-notes-by-title.md "Referencing notes by title"
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. For a comprehensive guide about contributing to open-source projects in general, [see here](https://blog.robsewell.com/blog/how-to-fork-a-github-repository-and-contribute-to-an-open-source-project/).
## 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!
To get yourself familiar with the codebase you can also browse [this repo](https://app.komment.ai/wiki/github/foambubble/foam)
## Diving In
We understand that diving in an unfamiliar codebase may seem scary,
to make it easier for new contributors we provide some resources:
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)!
## Contributing
If you're interested in contributing, this short guide will help you get things set up locally (assuming [node.js >= v18](https://nodejs.org/) and [yarn](https://yarnpkg.com/) are already installed on your system).
You can also use the provided [[devcontainers]] to avoid installing dependencies locally. With the Dev Containers extension installed, open the repository in VS Code and run **Dev Containers: Reopen in Container**.
1. Fork the project to your Github account by clicking the "Fork" button on the top right hand corner of the project's [home repository page](https://github.com/foambubble/foam).
3. Install the necessary dependencies by running this command from the root of the cloned repository:
`yarn install`
4. From the repository 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/main/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/ee7a8919761f168d3931079adf21c5ad4d63db59/packages/foam-core) - Powers the core functionality in Foam across all platforms.
- [/packages/foam-vscode](https://github.com/foambubble/foam/tree/main/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
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/main/.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)).
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!
### Submitting a Pull Request (PR)
After you have made your changes to your copy of the project, it is time to try and merge those changes into the public community project.
1. Return to the project's [home repository page](https://github.com/foambubble/foam).
2. Github should show you an button called "Compare & pull request" linking your forked repository to the community repository.
3. Click that button and confirm that your repository is going to be merged into the community repository. See [this guide](https://blog.robsewell.com/blog/how-to-fork-a-github-repository-and-contribute-to-an-open-source-project/) for more specifics.
4. Add as many relevant details to the PR message to make it clear to the project maintainers and other members of the community what you have accomplished with your new changes. Link to any issues the changes are related to.
5. Your PR will then need to be reviewed and accepted by the other members of the community. Any discussion about the changes will occur in your PR thread.
6. Once reviewed and accept you can complete the merge request!
7. Finally rest and watch the sun rise on a grateful universe... Or start tackling the other open issues ;)
---
Feel free to modify and submit a PR if this guide is out-of-date or contains errors!
---
[//begin]: # "Autogenerated link references for markdown compatibility"
[principles]: ../principles.md "Principles"
[code-of-conduct]: code-of-conduct.md "Code of Conduct"
[devcontainers]: devcontainers.md "Using Dev Containers"
Foam provides a [devcontainer](https://devcontainer.ai/) configuration to make it easy to contribute without installing Node and Yarn locally.
## Quick start
1. Install [VS Code](https://code.visualstudio.com/) and the [Dev Containers](https://aka.ms/vscode-remote/download/extension) extension.
2. Open the Foam repository in VS Code.
3. Run **Dev Containers: Reopen in Container** from the command palette.
This will build a Docker image with Node 18 and install dependencies using `yarn install`. Once ready you can run the usual build and test commands from the integrated terminal.
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]]` and note embeds.
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 `[[MediaWiki]]` links.** See [[wikilinks]] for more details.
- **You can embed other notes using `![[note]]` syntax.** This supports various modifiers like `content![[note]]` or `full-card![[note]]` to control how content is displayed.
`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,11 +61,11 @@ 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]]
- Finding all documents with instances of `[[link]]`
- Visualisations
- Visualizations
- Full text search
- Or, if search is too expensive/complex, when given a list of file names and line/column positions from VS Code search API, can return the document context (e.g. full paragraph, preceding/following line etc)
@@ -96,13 +96,12 @@ Useful for knowing what needs to be supported. See [[feature-comparison]].
- [[foam-core-2020-07-11]]
[//begin]: # "Autogenerated link references for markdown compatibility"
# 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 possibilities 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 the 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 property 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 looked up 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:
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,19 +59,21 @@ 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:
- For edit-time
- Make edit-time link reference definition generation optional via user settings. They should be on by default, and generating valid markdown links with a relative path to a `.md` file.
- Make format of the link reference definition configurable (whether to include '.md' or not)
- Out of recommended extensions, currently only "markdown links" doesn't support them (?). However even its [code](https://github.com/tchayen/markdown-links/blob/master/src/parsing.ts#L25) seems to include wikilink parser, so it might just be a bug?
- Out of recommended extensions, currently only "markdown links" doesn't support them (?). However even its [code](https://github.com/tchayen/markdown-links/blob/main/src/parsing.ts#L25) seems to include wikilink parser, so it might just be a bug?
- For build-time
- To satisfy mutually incompatible constraints between GitHub UI, VSCode UI, and GitHub Pages, we should add a pre-processing/build step for pushing to GitHub Pages.
- 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
@@ -116,13 +118,15 @@ The potential solution:
enum LinkReferenceDefinitions {
Off, // link reference definitions are not generated
WithoutExtensions // link reference definitions do not contain file extenions
WithoutExtensions // link reference definitions do not contain file extensions
}
```
- 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 +139,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"
Items we plan on working next. Items in this stage don't need to have an owner, but before we start working on them should have enough specification that they can be picked up and worked on without having to seek consensus.
If you want to pick up work in this category, you should have a plan on how long the implementation will approximately take so we don't block progress by sitting on high priority issues.
- [[workspace-janitor]]
## Backlog
Everything else, categorised into themes. Just because something is on this list doesn't mean it'll get done. If you're interested in working on items in this category, check the [[contribution-guide]] for how to get started.
If a roadmap item is a stub, **consider** opening a [GitHub issue](https://github.com/foambubble/foam/issues) to start a conversation to avoid situations where the implementation does not fit long term vision and roadmap. _Note that this is optional. The only centralised governance in Foam is to decide what ends up in the official [template](https://github.com/foambubble/foam-template), [documentation](https://github.com/foambubble/foam) and [extension](https://github.com/foambubble/foam/tree/master/packages/foam-vscode). You are free to build whatever you want for yourself, and we'd love if you shared it with us, but you are by no means obligated to do so!_
If a roadmap item is a stub, **consider** opening a [GitHub issue](https://github.com/foambubble/foam/issues) to start a conversation to avoid situations where the implementation does not fit long term vision and roadmap. _Note that this is optional. The only centralised governance in Foam is to decide what ends up in the official [template](https://github.com/foambubble/foam-template), [documentation](https://github.com/foambubble/foam) and [extension](https://github.com/foambubble/foam/tree/main/packages/foam-vscode). You are free to build whatever you want for yourself, and we'd love if you shared it with us, but you are by no means obligated to do so!_
**When creating GitHub issues to discuss roadmap items, link them here.**
@@ -29,7 +25,7 @@ If a roadmap item is a stub, **consider** opening a [GitHub issue](https://githu
| 8 `[[/house/todo]]` | ✘ incorrect path from repo root | ✘ incorrect path from repo root |
## Non-unique identifiers
We can't prevent non-unique identifiers from occurring in Foam (first and foremost because a file could be edited with another editor) but we can flag them.
Therefore Foam follows the following strategy instead:
1. there is a clear resolution mechanism (alphabetic) so that if nothing changes a non-unique identifier will always return the same note. Resolution has to be deterministic
2. a diagnostic entry (warning or error) is showed to the user for non-unique identifiers, so she knows that she's using a "risky" identifier
1. The quick resolution for this item will show the available unique identifiers matching the non-unique one
## Thanks
Thanks to [@memplex](https://github.com/memeplex) for helping with the thinking around this proposal.
@@ -6,15 +6,15 @@ If you're interested in working on it, please start a conversation in [GitHub is
## Notes
One of Roam's big features is the ability to find all instances of a reference, create a page for it and update all the references to link to the new page.
One of Foam's big features is the ability to find all instances of a reference, create a page for it and update all the references to link to the new page.
Implementing this is on the [[roadmap]], but for the time being you can achieve similar things by:
- `Cmd` + `Shift` + `F` ( `Ctrl` + `Shift` + `F` on Windows ) to find all the references, e.g. "Cat food"
- `Cmd` + `Shift` + `H` ( `Ctrl` + `Shift` + `F` on Windows ) to replace them with [[cat-food]].
- `Cmd` + `Shift` + `H` ( `Ctrl` + `Shift` + `H` on Windows ) to replace them with [[cat-food]].
- Click any of the references to create a new note.
[//begin]: # "Autogenerated link references for markdown compatibility"
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]]`.
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]]`:
- **It needs to have a single top level `# Heading`.**
- This will be used as document title.
- [[decision-needed]] Do we need it?
- [[decision-needed]] How much to deviate from just markdown
- **File name should not contain spaces,** e.g. `foam-file-format.md` is a valid name, but `Foam File Format.md` is not.
- This is a temporary limitation and will be lifted in future versions.
- Technically this actually works already, but may have some edge cases you don't want to deal with if you can avoid it.
- **File name should have extension `.md` or `.markdown`**
- 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.
[//begin]: # "Autogenerated link references for markdown compatibility"
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.
## 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.
Log into your Vercel account. (Create one if you don't have it already.)
Import your project. Select `_layouts/public` as your root directory and click **Continue**. Then name your project and click **Deploy**.
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
-`graphMiddleware?: Middleware` an object that can intercept calls to the Foam graph
-`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"
- [Links/Graphs/BackLinks don't work. How do I enable them?](#linksgraphsbacklinks-dont-work-how-do-i-enable-them)
## 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]]
[//begin]: # "Autogenerated link references for markdown compatibility"
[link-formatting-and-autocompletion]: link-formatting-and-autocompletion.md "Link Formatting and Autocompletion"
[//end]: # "Autogenerated link references"
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.