Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jurica Bacurin <jurica@bacurin.de>
Ran tests against the PR, all pass.
Fallback wiki link resolution by matching on title or path
Add new template variables when generating Markdown links
Add a {{substring}} template helper
- label:I searched the existing discussions for help
required:true
- type:textarea
id:help
attributes:
label:How can we help you?
validations:
required:true
- type:markdown
attributes:
value:|
:warning:Unfortunately, my time is limited and I can't offer reliable user support. I might answer if you catch me on a slow day, or hopefully someone else will.
:warning:Unfortunately, my time is limited and I can't offer reliable user support. I might answer if you catch me on a slow day, or hopefully someone else will.
- type:checkboxes
id:checks
attributes:
label:If you need help, open a discussion
options:
- label:I will [create a new discussion](https://github.com/zk-org/zk/discussions/new?category=help) instead of an issue.
stale-issue-message:'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs in the next 5 days.'
close-issue-message:'This issue was closed because it has been stalled for 5 days with no activity.'
All notable changes to this project will be documented in this file.
<!--## Unreleased-->
## Unreleased
## 0.14.1
### Fixed
* Fixed parsing large notes @khimaros in https://github.com/zk-org/zk/pull/339
* fix day range parsing (zk-org/zk#382) by @tjex in https://github.com/zk-org/zk/pull/384
* accept tripple dash file URIs as valid links by @tjex in https://github.com/zk-org/zk/pull/391
* fix(lsp): fix trigger completion of zk LSP by @Rahlir in https://github.com/zk-org/zk/pull/397
* fix(lsp): ignore diagnostic check within code blocks by @Rahlir in https://github.com/zk-org/zk/pull/399
* allow notebook as hidden dir by @tjex in https://github.com/zk-org/zk/pull/402
## 0.14.0
### Added
* New [`tool.shell`](docs/tool-shell.md) configuration key to set a custom shell (contributed by [@lsvmello](https://github.com/zk-org/zk/pull/302)).
* New [`notebook.dir`](docs/config-notebook.md) configuration key to set the default notebook (contributed by [@lsvmello](https://github.com/zk-org/zk/pull/304)).
### Changed
* The `note.ignore` configuration property was renamed to `note.exclude`, to be more consistent with the CLI flags.
### Fixed
* Fixed LSP positions using UTF-16 offsets (contributed by [@wrvsrx](https://github.com/zk-org/zk/pull/317)).
## 0.13.0
### Added
* LSP:
* `zk.new` now returns the created note's content in its output (`content`), and has two new options:
* `dryRun` will prevent `zk.new` from creating the note on the file system.
* `insertContentAtLocation` can be used to insert the created note's content into an arbitrary location.
* A new `zk.link` command to insert a link to a given note (contributed by [@psanker](https://github.com/zk-org/zk/pull/284)).
## 0.12.0
### Added
* LSP: Support for external URLs with `documentLink`.
* New `{{date}}` template helper to obtain a date object from natural language (contributed by [@zalegrala](https://github.com/zk-org/zk/pull/262)).
```
Get a relative date using natural language:
{{date "next week"}}
Format a date returned by `get-date`:
{{format-date (date "monday") "timestamp"}}
```
* `zk list` now support multiple `--match`/`-m` flags, which allows to search for several tokens appearing in any order in the notes (contributed by [@rktjmp](https://github.com/zk-org/zk/pull/268)).
### Changed
* **Breaking change:** The `{{date}}` template helper was renamed to `{{format-date}}`. You might need to update your configuration and templates.
### Fixed
* [#243](https://github.com/zk-org/zk/issues/243) LSP: Fixed finding backlink references for notes in a folder.
* [#254](https://github.com/zk-org/zk/issues/254) Fixed SQL error when pairing `--link-to` and `--linked-by`.
## 0.11.1
### Changed
* `zk new` now requires the `--interactive`/`-i` flag to read the note body from a pipe or standard input. [See rational](https://github.com/zk-org/zk/pull/242#issuecomment-1182602001).
### Fixed
* [#244](https://github.com/zk-org/zk/issues/244) Fixed `zk new` waiting for `Ctrl-D` to proceed (contributed by [@pkazmier](https://github.com/zk-org/zk/pull/242)).
## 0.11.0
### Added
* Use regular expressions when searching for notes with `--match`.
```sh
# Find notes containing emails.
$ zk list --match-strategy re --match ".+@.+"
$ zk list -Mr -m ".+@.+"
```
### Changed
* The flags `--exact-match`/`-e` are deprecated in favor of `--match-strategy exact`/`-Me`.
### Deprecated
* The LSP server does not support resolving a wiki link to a note title anymore.
* For example, `[[Planet]]` can match a note with filename `i4w0 Planet.md` but not `i4w0.md` with a Markdown title `Planet` anymore.
* This "smart" fallback resolution based on note titles was too fragile and not supported by the `zk` CLI.
### Fixed
* [#233](https://github.com/zk-org/zk/issues/233) Hide index progress in non-interactive shells.
* [#235](https://github.com/zk-org/zk/issues/235) Fix LSP link recognition with unicode (contributed by [@zkbpkp](https://github.com/zk-org/zk/issues/235)).
* [#236](https://github.com/zk-org/zk/issues/236) Fix updating links after creating a new note.
* [#239](https://github.com/zk-org/zk/discussions/239) Support standard input via shell redirection with `zk new`.
## 0.10.1
### Changed
* Removed the dependency on `libicu`.
### Fixed
* Indexed links are now automatically updated when adding a new note, if it is a better match than the previous link target.
## 0.10.0
### Added
* New `--date` flag for `zk new` to set the current date manually.
* New `--id` flag for `zk new` to skip ID generation and use a provided value (contributed by [@skbolton](https://github.com/zk-org/zk/pull/183)).
* [#144](https://github.com/zk-org/zk/issues/144) LSP auto-completion of YAML frontmatter tags.
* [zk-nvim#26](https://github.com/zk-org/zk-nvim/issues/26) The LSP server doesn't use `additionalTextEdits` anymore to remove the trigger characters when completing links.
* You can customize the default behavior with the [`use-additional-text-edits` configuration key](docs/config-lsp.md).
* [#163](https://github.com/zk-org/zk/issues/163) Use the `ZK_SHELL` environment variable to override the shell for `zk` only.
* [#173](https://github.com/zk-org/zk/issues/173) Support for double star globbing in `note.ignore` config option.
* [#137](https://github.com/zk-org/zk/issues/137) Customize the `fzf` options used by `zk`'s interactive modes with the [`fzf-options`](docs/tool-fzf.md) config option (contributed by [@Nelyah](https://github.com/zk-org/zk/pull/154)).
* [#168](https://github.com/zk-org/zk/discussions/168) Customize the `fzf` key binding to create new notes with the [`fzf-bind-new`](docs/tool-fzf.md) config option.
### Changed
* The default `fzf` key binding to create a new note with `zk edit --interactive` was changed to `Ctrl-E`, to avoid conflict with the default `Ctrl-N` binding.
### Fixed
* [#126](https://github.com/zk-org/zk/issues/126) Embedded image links shown as not found.
* [#152](https://github.com/zk-org/zk/issues/152) Incorrect timezone for natural dates.
* [#170](https://github.com/zk-org/zk/issues/170) Broken wiki links in subdirectories.
* [#185](https://github.com/zk-org/zk/issues/185) Don't parse a Markdown table header as a colon tag.
## 0.9.0
### Added
* New LSP commands:
* [`zk.list`](docs/editors-integration.md#zklist) to search for notes.
* [`zk.tag.list`](docs/editors-integration.md#zktaglist) to retrieve the list of tags.
* `--debug` mode which prints a stacktrace on `SIGINT`.
### Fixed
* [#111](https://github.com/zk-org/zk/issues/111) Filenames take precedence over folders when matching a sub-path with wiki links.
* [#118](https://github.com/zk-org/zk/issues/118) Fix infinite loop when parsing a single-character hashtag.
* [#121](https://github.com/zk-org/zk/issues/121) Take into account the `--no-input` flag with `zk init`.
* [#120](https://github.com/zk-org/zk/discussions/120) Support RFC 3339 dates with the time flags (e.g. `--created-before`).
## 0.8.0
### Added
* New `zk graph --format json` command which produces a JSON graph of the notes matching the given criteria.
* New template variables `filename` and `filename-stem` when formatting notes (e.g. with `zk list --format`) and for the [`fzf-line`](docs/tool-fzf.md) config key.
* Customize how LSP completion items appear in your editor when auto-completing links with the [`[lsp.completion]` configuration section](docs/config-lsp.md).
```toml
[lsp.completion]
# Show the note title in the completion pop-up, or fallback on its path if empty.
note-label = "{{title-or-path}}"
# Filter out the completion pop-up using the note title or its path.
note-filter-text = "{{title}} {{path}}"
# Show the note filename without extension as detail.
note-detail = "{{filename-stem}}"
```
* New `--dry-run` flag for `zk new` which prints out the path and content of the generated note instead of saving it to the file system.
* New `--verbose` flag for `zk index` which prints detailed information about the indexing process.
* You can now filter through the [YAML frontmatter](docs/note-frontmatter.md) with `zk list --interactive`.
### Fixed
* [#89](https://github.com/zk-org/zk/issues/89) Calling `zk index` from outside the notebook (contributed by [@adamreese](https://github.com/zk-org/zk/pull/90)).
* [#98](https://github.com/zk-org/zk/issues/98) Index wiki links using partial paths for `--linked-by` and `--link-to`.
* [#98](https://github.com/zk-org/zk/issues/98) Ignore spaces around the pipe in wiki links for LSP diagnostics.
## 0.7.0
### Added
* List the tags found in your notebook with `zk tag list`.
* Many options are available to customize the output, including JSON serialization. See `zk tag list --help`.
* Support for LSP references to browse the backlinks of the current note, if the caret is not over a link.
* New template variables are available when [generating custom Markdown links with `link-format`](docs/note-format.md).
* `filename`, `path`, `abs-path` and `rel-path` for many path flavors.
* `metadata` to use information (e.g. `id`) from the YAML frontmatter.
* The LSP server is now matching wiki links to any part of a note's path or its title.
* Given the note `book/z5mj Information Graphics.md` with the title "Book Review of Information Graphics", the following wiki links would work from a note located under `journal/2020-09-25.md`:
```markdown
[[../book/z5mj]]
[[book/z5mj]]
[[z5mj]]
[[book review information]]
[[Information Graphics]]
```
* Use the `{{abs-path}}` template variable when [formatting notes](docs/template-format.md) to print the absolute path to the note (contributed by [@pstuifzand](https://github.com/zk-org/zk/pull/60)).
* A new `{{substring s index length}}` template helper extracts a portion of a given string, e.g.:
* `{{substring 'A full quote' 2 4}}` outputs `full`
* `{{substring 'A full quote' -5 5}` outputs `quote`
### Fixed
* UTF-8 handling in the LSP server.
* [#78](https://github.com/zk-org/zk/issues/78) Do not exclude notes containing broken links from the index.
* Allow setting the `--working-dir` and `--notebook-dir` flags before the `zk` subcommand when using aliases, e.g. `zk -W ~/notes my-alias`.
* [#86](https://github.com/zk-org/zk/issues/86) Index encoded Markdown links.
## 0.6.0
### Added
* Use JSON formats with `zk list` for easy post-processing:
* `--format json` prints a plain JSON array.
* `--format jsonl` prints one JSON note object per line, according to [JSON Lines](https://jsonlines.org/).
* The new `{{json}}` template helper serializes any template context variable into a valid JSON value, e.g.:
* `{{json title}}` prints with quotes `"An interesting note"`
* `{{json .}}` serializes the full template context as a JSON object.
* Use `--header` and `--footer` options with `zk list` to print arbitrary text at the start or end of the list.
* Support for LSP references to browse the backlinks of the link under the caret (contributed by [@pstuifzand](https://github.com/zk-org/zk/pull/58)).
* New [`note.ignore`](docs/config-note.md) configuration option to ignore files matching the given path globs when indexing notes.
```yaml
[note]
ignore = [
"log-*.md"
"drafts/*"
]
```
### Fixed
* [#16](https://github.com/zk-org/zk/issues/16) Links with section anchors, e.g. `[[filename#section]]`.
* Unicode support in wiki links. If you use accents or ideograms, please run `zk index --force` after upgrading to fix your index.
## 0.5.0
### Added
* [Editor integration through LSP](https://github.com/zk-org/zk/issues/22):
* New code actions to create a note using the current selection as title.
* Custom commands to [run `new` and `index` from your editor](docs/editors-integration.md#custom-commands).
* Diagnostics to [report dead links or wiki link titles](docs/config-lsp.md).
* Auto-complete only the path of a Markdown link by typing `[custom title]((`.
* Customize the format of `fzf`'s lines [with your own template](docs/tool-fzf.md).
* Automatically index the notebook when saving a note with an LSP-enabled editor.
* This ensures that tags and notes auto-completion lists are up-to-date.
### Fixed
* Creating a new note from `fzf` in a directory containing spaces.
* Fix completion with Neovim's built-in LSP client (contributed by [@cormacrelf](https://github.com/zk-org/zk/pull/39)).
## 0.4.0
@ -10,18 +278,18 @@ All notable changes to this project will be documented in this file.
* Interactive wizard for the `zk init` command.
* An experimental Language Server for LSP-compatible editors:
* Auto-complete Markdown links with `[[` (setup wiki-links in the [note formats configuration](docs/note-format.md))
* Auto-complete Markdown links with `[[` (setup wikilinks in the [note formats configuration](docs/note-format.md))
* Auto-complete [hashtags and colon-separated tags](docs/tags.md).
* Preview the content of a note when hovering a link.
* Navigate in your notes by following internal links.
* [And more to come...](https://github.com/mickael-menu/zk/issues/22)
* [And more to come...](https://github.com/zk-org/zk/issues/22)
* See [the documentation](docs/editors-integration.md) for configuration samples.
* Pair `--match` with `--exact-match` / `-e` to search for (case insensitive) exact occurrences in your notes.
* This can be useful when looking for terms including special characters, such as `[[name]]`.
* Generating links to notes.
* Use the `{{link}}` template variable when [formatting notes](docs/template-format.md) to print a link to the note, relative to the working directory.
* Use the `{{format-link path title}}` template helper to render a custom link.
* Customize the link format from the [note formats settings](docs/note-format.md). You can for example choose regular Markdown links, Wiki-links or a custom format.
* Customize the link format from the [note formats settings](docs/note-format.md). You can for example choose regular Markdown links, wiki links or a custom format.
### Changed
@ -59,7 +327,7 @@ All notable changes to this project will be documented in this file.
### Fixed
* [#4](https://github.com/mickael-menu/zk/issues/4) Terminal borked when piping content with Vim
* [#4](https://github.com/zk-org/zk/issues/4) Terminal borked when piping content with Vim
## 0.2.1
@ -92,3 +360,4 @@ All notable changes to this project will be documented in this file.
* Renamed `--linking-to` filtering option to `--link-to`.
* Multiple `--extra` variables are now separated by `,` instead of `;`.
- `CGO_ENABLED=1` enables CGO, which is required by the `mattn/go-sqlite3` dependency.
- `GOARCH=arm64` is only required for Apple Silicon chips.
- `-tags "fts5"` enables the FTS option with `mattn/go-sqlite3`, which handles much of the magic behind `zk`'s `--match` filtering option.
- ``-ldflags "-X=main.Version=`git describe --tags --match v[0-9]* 2> /dev/null` -X=main.Build=`git rev-parse --short HEAD`"`` will automatically set `zk`'s build and version numbers using the latest Git tag and commit SHA.
### Automated tests
The project is vetted with two different kind of automated tests: unit tests and end-to-end tests.
#### Unit tests
Unit tests are using the standard [Go testing library](https://pkg.go.dev/testing). To execute them, use the command `make test`.
They are ideal for testing parsing output or individual API edge cases and minutiae.
#### End-to-end tests
Most of `zk`'s functionality is tested with functional tests ran with [`tesh`](https://github.com/mickael-menu/tesh), which you can execute with `make tesh` (or `make teshb`, to debug whitespaces changes).
When addressing a GitHub issue, it's a good idea to begin by creating a `tesh` file in `tests/issue-XXX.tesh`. If a starting notebook state is required, it can be added under `tests/fixtures`.
If you modify the output of `zk`, you may disrupt some `tesh` files. You can use `make tesh-update` to automatically update them with the correct output.
### CI workflows
Several GitHub action workflows are executed when pull requests are merged or releases are created.
- `.github/workflows/build.yml` checks that the project can be built and the tests still pass.
- `.github/workflows/codeql.yml` runs static analysis to vet code quality.
- `.github/workflows/gh-pages.yml` deploy the documentation files to GitHub Pages.
- `.github/workflows/release.yml` submits a new version to Homebrew when a Git version tag is created.
- `.github/workflows/triage.yml` automatically tags old issues and PRs as staled.
## Releasing a new version
When `zk` is ready to be released, you can update the `CHANGELOG.md` ([for example](https://github.com/zk-org/zk/commit/ea4457ad671aa85a6b15747460c6f2c9ad61bf73)) and create a new Git version tag (for example `v0.13.0`). Make sure you follow the [Semantic Versioning](https://semver.org) scheme.
Then, create [a new GitHub release](https://github.com/zk-org/zk/releases) with a copy of the latest `CHANGELOG.md` entries and the binaries for all supported platforms.
Binaries can be created automatically using `make dist-linux` and `make dist-macos`.
Unfortunately, `make dist-macos` must be run manually on both an Apple Silicon and Intel chips. The Linux builds are created using Docker and [these custom images](https://github.com/zk-org/zk-xcompile), which are hosted via [ghcr.io within zk-org](https://github.com/orgs/zk-org/packages/container/package/zk-xcompile).
This process is convoluted because `zk` requires CGO with `mattn/go-sqlite3`, which prevents using Go's native cross-compilation. Transitioning to a CGO-free SQLite driver such as [cznic/sqlite](https://gitlab.com/cznic/sqlite) could simplify the distribution process significantly.
<p>Looking for a quick usage example? <ahref="docs/getting-started.md">Let's get started</a>.</p>
</div>
Looking for a quick usage example? [Let's get started](docs/getting-started.md).
## Description
`zk` is a command-line tool helping you to maintain a plain text [Zettelkasten](https://zettelkasten.de/introduction/) or [personal wiki](https://en.wikipedia.org/wiki/Personal_wiki).
@ -14,9 +16,10 @@
* [Creating notes from templates](docs/note-creation.md)
* [Advanced search and filtering capabilities](docs/note-filtering.md) including [tags](docs/tags.md), links and mentions
* [Integration with your favorite editors](docs/editors-integration.md):
* [`zk.nvim`](https://github.com/megalithic/zk.nvim) for Neovim 0.5+, maintained by [Seth Messer](https://github.com/megalithic)
* [`zk-vscode`](https://github.com/mickael-menu/zk-vscode) for Visual Studio Code
* [`zk-nvim`](https://github.com/zk-org/zk-nvim) for Neovim 0.8+
* [`zk-vscode`](https://github.com/zk-org/zk-vscode) for Visual Studio Code
* (*unmaintained*) [`zk.nvim`](https://github.com/megalithic/zk.nvim) for Neovim 0.5+ by [Seth Messer](https://github.com/megalithic)
* [Interactive browser](docs/tool-fzf.md), powered by `fzf`
* [Git-style command aliases](docs/config-alias.md) and [named filters](docs/config-filter.md)
* [Made with automation in mind](docs/automation.md)
@ -36,47 +39,62 @@
## Install
[Check out the latest release](https://github.com/mickael-menu/zk/releases) for pre-built binaries for macOS and Linux (`zk` was not tested on Windows).
### Build from scratch
[Check out the latest release](https://github.com/zk-org/zk/releases) for pre-built binaries for macOS and Linux (`zk` was not tested on Windows).
Make sure you have a working [Go installation](https://golang.org/), then clone the repository:
* [send notes for processing by other programs](external-processing.md)
* [create a note with initial content](note-creation.md) from a standard input pipe
If you find out that `zk` does not behave as expected or could communicate better with other programs, [please post an issue](https://github.com/mickael-menu/zk/issues).
If you find out that `zk` does not behave as expected or could communicate better with other programs, [please post an issue](https://github.com/zk-org/zk/issues).
@ -6,9 +6,10 @@ Declaring your own aliases is a great way to make your experience with `zk` easi
## Configuring aliases
Command aliases are declared in your [configuration file](config.md), under the `[alias]` section. They are executed with `$SHELL -c`, which allows you to:
Command aliases are declared in your [configuration file](config.md), under the `[alias]` section. They are executed with [your default shell](tool-shell.md), which allows you to:
* expand arguments with `$@` or `$*`
* [it is recommended to wrap `$@` in quotes](https://github.com/zk-org/zk/issues/316#issuecomment-1543564168)
* expand environment variables
* run several commands with `&&`
* pipe several commands with `|`
@ -17,7 +18,7 @@ An alias can call other aliases but cannot call itself. This enables you to over
```toml
[alias]
edit = "zk edit --interactive $@"
edit = 'zk edit --interactive "$@"'
```
When running an alias, the `ZK_NOTEBOOK_DIR` environment variable is set to the absolute path of the current notebook. You can use it to run commands working no matter the location of the working directory.
Each [notebook](notebook.md) contains a configuration file used to customize your experience with `zk`. This file is located at `.zk/config.toml` and uses the [TOML format](https://github.com/toml-lang/toml). It is composed of several optional sections:
* `[notebook]` configures the [default notebook](config-notebook.md)
* `[note]` sets the [note creation rules](config-note.md)
* `[extra]` contains free [user variables](config-extra.md) which can be expanded in templates
* `[group]` defines [note groups](config-group.md) with custom rules
* `[format]` configures the [note format settings](note-format.md), such as Markdown options.
* `[format]` configures the [note format settings](note-format.md), such as Markdown options
* `[tool]` customizes interaction with external programs such as:
* [your default editor](tool-editor.md)
* [your default shell](tool-shell.md)
* [your default pager](tool-pager.md)
* [`fzf`](tool-fzf.md)
* `[lsp]` setups the [Language Server Protocol settings](config-lsp.md) for [editors integration](editors-integration.md)
* `[filter]` declares your [named filters](config-filter.md)
* `[alias]` holds your [command aliases](config-alias.md)
@ -24,6 +27,10 @@ Notebook configuration files will inherit the settings defined in the global con
Here's an example of a complete configuration file:
Let's assume you want to write daily notes named like `2021-02-16.md` in a `journal/daily` sub-directory. This common use case is a good fit for creating a [note group](config-group.md) overriding the default [note creation](note-creation.md) settings.
First, create a `group` entry in the [configuration file](config.md) to set the note settings for this directory. Refer to the [template syntax reference](template.md) to understand how to use the `{{date}}` helper.
First, create a `group` entry in the [configuration file](config.md) to set the note settings for this directory. Refer to the [template syntax reference](template.md) to understand how to use the `{{format-date}}` helper.
```toml
[group.daily]
@ -10,8 +10,8 @@ First, create a `group` entry in the [configuration file](config.md) to set the
paths = ["journal/daily"]
[group.daily.note]
# %Y-%m-%d is actually the default format, so you could use {{date now}} instead.
filename = "{{date now '%Y-%m-%d'}}"
# %Y-%m-%d is actually the default format, so you could use {{format-date now}} instead.
filename = "{{format-date now '%Y-%m-%d'}}"
extension = "md"
template = "daily.md"
```
@ -19,7 +19,7 @@ template = "daily.md"
Next, create a template file under `.zk/templates/daily.md` to render the note content. Here we used the date again to generate a title like "February 16, 2021".
```markdown
# {{date now "long"}}
# {{format-date now "long"}}
What did I do today?
```
@ -43,3 +43,7 @@ Let's unpack this alias:
* `$ZK_NOTEBOOK_DIR` is set to the absolute path of the current [notebook](notebook.md) when running an alias. Using it allows you to run `zk daily` no matter where you are in the notebook folder hierarchy.
* We need to use double quotes around `$ZK_NOTEBOOK_DIR`, otherwise it will not be expanded.
If you want to edit today's note, simply use this alias:
There are several extensions available to integrate `zk` in your favorite editor:
* [`zk.nvim`](https://github.com/megalithic/zk.nvim) for Neovim 0.5+, maintained by [Seth Messer](https://github.com/megalithic)
* [`zk-vscode`](https://github.com/mickael-menu/zk-vscode) for Visual Studio Code
* [`zk-nvim`](https://github.com/zk-org/zk-nvim) for Neovim 0.5+
* [`zk-vscode`](https://github.com/zk-org/zk-vscode) for Visual Studio Code
## Language Server Protocol
@ -13,16 +13,24 @@ There are several extensions available to integrate `zk` in your favorite editor
* Auto-complete [hashtags and colon-separated tags](tags.md).
* Preview the content of a note when hovering a link.
* Navigate in your notes by following internal links.
* [And more to come...](https://github.com/mickael-menu/zk/issues/22)
* Create a new note using the current selection as title.
* Diagnostics for dead links and wiki-links titles.
* [And more to come...](https://github.com/zk-org/zk/issues/22)
You can configure some of these features in your notebook's [configuration file](config-lsp.md).
To start the Language Server, use the `zk lsp` command. Refer to the following sections for editor-specific examples. [Feel free to share the configuration for your editor](https://github.com/mickael-menu/zk/issues/22).
### Editor LSP configurations
### Vim and Neovim
To start the Language Server, use the `zk lsp` command. Refer to the following sections for editor-specific examples. [Feel free to share the configuration for your editor](https://github.com/zk-org/zk/issues/22).
#### Vim and Neovim 0.4
#### Vim and Neovim
##### Vim and Neovim 0.4
With [`coc.nvim`](https://github.com/neoclide/coc.nvim), run `:CocConfig` and add the following in the settings file:
-- Add keybindings here, see https://github.com/neovim/nvim-lspconfig#keybindings-and-completion
end })
```
</details>
### Sublime Text
#### Sublime Text
Install the [Sublime LSP](https://github.com/sublimelsp/LSP) package, then run the **Preferences: LSP Settings** command. Add the following to the settings file:
@ -80,7 +119,133 @@ Install the [Sublime LSP](https://github.com/sublimelsp/LSP) package, then run t
}
}
```
</details>
### Visual Studio Code
#### Visual Studio Code
Install the [`zk-vscode`](https://marketplace.visualstudio.com/items?itemName=mickael-menu.zk-vscode) extension from the Marketplace.
### Custom commands
Using `zk`'s LSP custom commands, you can call `zk` commands right from your editor. Please refer to your editor's documentation on how to bind keyboard shortcuts to custom LSP commands.
#### `zk.index`
This LSP command calls `zk index` to refresh your notebook's index. It can be useful to make sure that the auto-completion is up-to-date. `zk.index` takes two arguments:
1. A path to a file or directory in the notebook to index.
2. <details><summary>(Optional) A dictionary of additional options (click to expand)</summary>
| `created` | string | No | Find notes created on the given date |
| `createdBefore` | string | No | Find notes created before the given date |
| `createdAfter` | string | No | Find notes created after the given date |
| `modified` | string | No | Find notes modified on the given date |
| `modifiedBefore` | string | No | Find notes modified before the given date |
| `modifiedAfter` | string | No | Find notes modified after the given date |
| `sort` | string array | No | Order the notes by the given criterion |
1. As the output of this command might be very verbose and put a heavy load on the LSP client, you need to explicitly set which note fields you want to receive with the `select` option. The following fields are available: `filename`, `filenameStem`, `path`, `absPath`, `title`, `lead`, `body`, `snippets`, `rawContent`, `wordCount`, `tags`, `metadata`, `created`, `modified` and `checksum`.
</details>
`zk.list` returns the found notes as a JSON array.
#### `zk.tag.list`
This LSP command calls `zk tag list` to return the list of tags in a notebook. It takes two arguments:
1. A path to any file or directory in the notebook, to locate it.
2. <details><summary>(Optional) A dictionary of additional options (click to expand)</summary>
@ -27,7 +27,7 @@ You can customize your experience using [custom templates](template.md) to gener
If you are not sure whether a note already exists for a particular subject, the "search or create" mode might be more appropriate than `zk new`. It is inspired by [Notational Velocity](https://notational.net/) and enables searching for an existing note or creating a new one in a single action.
From `zk`'s interactive edit screen, press `Ctrl-N` to create a new note using the current search query as title.
From `zk`'s interactive edit screen, press `Ctrl-E` to create a new note using the current search query as title.
<divalign="center"><imgalt="Create a note"width="85%"src="assets/media/new2.svg"/></div>
@ -10,15 +10,21 @@ By default, `zk new` will start [your editor](tool-editor.md) after creating the
If you are not sure whether a note already exists for a particular subject, the "search or create" mode might be more appropriate than `zk new`. It is inspired by [Notational Velocity](https://notational.net/) and enables searching for an existing note or creating a new one in a single action.
This option is available when running `zk edit --interactive`, which spawns [`fzf`](tool-fzf.md) to filter selected notes. From `fzf`, press `Ctrl-N` to create a new note using the current search query as title.
This option is available when running `zk edit --interactive`, which spawns [`fzf`](tool-fzf.md) to filter selected notes. From `fzf`, press `Ctrl-E` to create a new note using the current search query as title.
## Create a note with initial content
Initial content can be fed to the template through a standard input pipe, which will be expandable with the `{{content}}` [template variable](template-creation.md).
Initial content can be fed to the template through standard input using `zk new --interactive`, which will be expandable with the `{{content}}` [template variable](template-creation.md).
For example, to use the content of the macOS clipboard as the initial content you can run:
Use `--match <query>` (or `-m`) to search through the title and body of notes.
The search is powered by a [full-text search](https://en.wikipedia.org/wiki/Full-text_search) database enabling near-instant results. Queries are not case-sensitive and terms are tokenized, which means that searching for `create` will also match `created` and `creating`.
The search is powered by different strategies to answer various use cases:
* `fts` (default) uses a [full-text search](https://en.wikipedia.org/wiki/Full-text_search) database to offer near-instant results and advanced search operators.
* `exact` is useful if you need to find patterns containing special characters.
* `re` enables regular expression for advanced use cases.
Change the currently used strategy with `--match-strategy <strategy>` (or `-M`). To set the default strategy, you can declare a [custom alias](config-alias.md):
```toml
[alias]
list = "zk list --match-strategy re $@"
```
The `--match` option may be given multiple times, where each argument will be combined with a boolean AND.
For example,
```sh
$ zk list --tag "recipe" --match "pizza -pineapple" --match "mushrooms"
```
Is equivalent to,
```sh
$ zk list --tag "recipe" --match "(pizza -pineapple) AND (mushrooms)"
```
### Full-text search (`fts`)
The default match strategy is powered by a [full-text search](https://en.wikipedia.org/wiki/Full-text_search) database enabling near-instant results. Queries are not case-sensitive and terms are tokenized, which means that searching for `create` will also match `created` and `creating`.
A syntax similar to Google Search is available for advanced search queries.
### Combining terms
```sh
# FTS is the default match strategy
$ zk list --match "tesla OR edison"
# ...but you can enable it explicitly.
$ zk list --match-strategy fts --match "tesla OR edison"
$ zk list -Mf -m "tesla OR edison"
```
#### Combining terms
By default, the search engine will find the notes containing all the terms in the query, in any order.
@ -83,7 +122,7 @@ Finally, you can filter out results by excluding a term with `NOT` (all caps) or
"tesla -car"
```
### Search in specific fields
#### Search in specific fields
If you want to search only in the title or body of notes, prefix a query with `title:` or `body:`.
@ -92,7 +131,7 @@ If you want to search only in the title or body of notes, prefix a query with `t
"body: (tesla OR edison)"
```
### Prefix terms
#### Prefix terms
Match any term beginning with the given prefix with a wildcard `*`.
@ -106,13 +145,25 @@ Prefixing a query with `^` will match notes whose title or body start with the f
"title: ^journal"
```
### Search for special characters
### Exact matches (`exact`)
If you need to find patterns containing special characters, such as an `email@addre.ss` or a `[[wiki-link]]`, use the `--exact-match` / `-e` option. The search will be case-insensitive.
If you need to find patterns containing special characters, such as an `email@addre.ss` or a `[[wiki-link]]`, use the `exact` match strategy. The search will be case-insensitive.
```sh
$ zk list --match-strategy exact --match "[[link]]"
$ zk list -Me -m "[[link]]"
```
$ zk list --exact-match --match "[[link]]"
$ zk list -em "[[link]]"
### Regular expressions (`re`)
For advanced use cases, you can use the `re` match strategy to search the notebook using regular expressions. The supported syntax is similar to the one used by Python or Perl. [See the full reference](https://golang.org/s/re2syntax).
:warning: Make sure to use quotes to prevent your shell from expanding wildcards.
@ -21,9 +21,22 @@ You can set up some features of `zk`'s Markdown parser from your [configuration
### Customizing the Markdown links generated by `zk`
By default, `zk` will generate regular Markdown links for internal links. If you prefer to use `[[Wiki Links]]` instead, set the `link-format` setting to `wiki`. If you want to override completely the link format, you can also set `link-format` to a [custom template](template.md). Two variables `path` and `title` are available in the template, for example to generate a wiki-link with a title:
By default, `zk` will generate regular Markdown links for internal links. If you prefer to use `[[Wiki Links]]` instead, set the `link-format` setting to `wiki`. If you want to override completely the link format, you can also set `link-format` to a [custom template](template.md). For example, to generate a wiki link using an ID from the frontmatter and a title:
```toml
[format.markdown]
link-format = "[[{{path}}|{{title}}]]"
link-format = "[[{{metadata.id}}|{{title}}]]"
```
The following variables are available in the template:
@ -6,6 +6,8 @@ To create a new notebook, simply run `zk init [<directory>]`.
Most `zk` commands are operating "Git-style" on the notebook containing the current working directory (or one of its parents). However, you can explicitly set which notebook to use with `--notebook-dir` or the `ZK_NOTEBOOK_DIR` environment variable. Setting `ZK_NOTEBOOK_DIR` in your shell configuration (e.g. `~/.profile`) can be used to define a default notebook which `zk` commands will use when the working directory is not in another notebook.
If the [default notebook](config-notebook.md) is set it will be used as `ZK_NOTEBOOK_DIR`, unless this environment variable is not already set.
## Anatomy of a notebook
Similarly to Git, a notebook is identified by the presence of a `.zk` directory at its root. This directory contains the only `zk`-specific files in your notebook:
@ -24,13 +24,39 @@ can generate (depending on the user config):
The second parameter `title` is optional.
### Date helper
### String helpers
The `{{date}}` helper formats the given date for display.
There are a couple of template helpers operating on strings.
#### Concat helper
The `{{concat s1 s2}}` helper concatenates two strings together. For example `{{concat '> ' 'A quote'}}` produces `> A quote`.
#### Substring helper
* The `{{substring s index length}}` helper extracts a portion of the given string. For example:
* `{{substring 'A full quote' 2 4}}` outputs `full`
* `{{substring 'A full quote' -5 5}}` outputs `quote`
### Date helpers
#### Date from natural string helper
You can get a date object from a natural human date (e.g. `tomorrow`, `2 weeks ago`, `2022-03-24`) using the `{{date}}` helper. It is most useful when paired with the `{{format-date}}` helper.
```
{{date "tomorrow"}}
{{format-date (date "last week") "timestamp"}}
```
#### Date formatting helper
The `{{format-date}}` helper formats the given date for display.
Template contexts usually provide a `now` variable which can be used to print the current date.
The default format output by `{{date <variable>}}` looks like `2009-11-17`, but you can choose a different format by providing a second argument, e.g. `{{date now "medium"}}`.
The default format output by `{{format-date <variable>}}` looks like `2009-11-17`, but you can choose a different format by providing a second argument, e.g. `{{format-date now "medium"}}`.
@ -44,7 +70,7 @@ The default format output by `{{date <variable>}}` looks like `2009-11-17`, but
| `timestamp-unix` | 1258490098 | Number of seconds since January 1, 1970 |
| `elapsed` | 12 years ago | Time elapsed since then in human-friendly format |
If none of the provided formats suit you, you can use a custom format using `strftime`-style placeholders, e.g. `{{date now "%m-%d-%Y"}}`. See `man strftime` for a list of placeholders.
If none of the provided formats suit you, you can use a custom format using `strftime`-style placeholders, e.g. `{{format-date now "%m-%d-%Y"}}`. See `man strftime` for a list of placeholders.
### Slug helper
@ -99,3 +125,17 @@ The `{{style}}` helper is mostly useful when formatting content for the command-
{{#style 'underline'}}Another text{{/style}}
```
### JSON helper
The `{{json}}` helper serializes its argument to a JSON value. This is useful to generate valid JSON objects, for example:
Besides the standard [`fzf` configuration options](https://github.com/junegunn/fzf) documented on its website, `zk` offers additional options you can set in the `[tool]` [configuration section](config.md).
If you wish to customize more of `fzf` behavior, [please post a feature request](https://github.com/mickael-menu/zk/issues).
If you wish to customize more of `fzf` behavior, [please post a feature request](https://github.com/zk-org/zk/issues).
## Preview command
@ -23,3 +23,70 @@ Or, if you prefer to preview more metadata, you can use a nested `zk` command.
[tool]
fzf-preview = "zk list --quiet --format full --limit 1 {-1}"
```
## Line format
With the `fzf-line` setting property, you can provide your own [template](template.md) to customize the format of each `fzf` line. The lines are used by `fzf` for the fuzzy matching, so if you want to search in the full note content, do not forget to add `{{body}}` in your custom template.
The default line template is `{{style "title" title-or-path}} {{style "understate" body}} {{style "understate" (json metadata)}}`.
Here's an example using different colors and showing the list of tags as #hashtags:
* `--preview-window wrap` Enable line wrapping in the preview window
## Key bindings
When running `fzf` with `zk edit --interactive`, you can [create a new note with the `Ctrl-E` key binding](note-creation.md#search-or-create-with-a-single-command). This binding is customizable with `fzf-bind-new`. You can also disable it by setting it to an empty string (`""`).
This is *currently* not supported on Windows (that defaults always to `cmd`).
You can customize which shell to use to run aliases and commands either from the [configuration file](config.md) or environment variables. In order of precedence, `zk` will use:
joinClauses=append(joinClauses,"JOIN notes_fts nsrc ON nsrc.rowid IN ("+d.joinIds(ids,",")+") AND nsrc.notes_fts MATCH mention_query(n.title, n.metadata)")
joinClauses=append(joinClauses,"JOIN notes_fts nsrc ON nsrc.rowid IN ("+joinNoteIDs(ids,",")+") AND nsrc.notes_fts MATCH mention_query(n.title, n.metadata)")