Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
6c9b0f1
finder: import fzf/src for native integration
alonswartz Jan 21, 2025
fd5683b
finder: initial implementation with hardcoded values
alonswartz Jan 22, 2025
d7699cf
finder: support custom input using end-of-options unix convention
alonswartz Jan 22, 2025
eec71b7
finder: support setting custom prompt text
alonswartz Jan 22, 2025
657015e
finder: support note preview
alonswartz Jan 22, 2025
28637a4
finder: support note preview syntax highlighting
alonswartz Jan 24, 2025
f5984e6
finder: support note preview inlineCode syntax highlighting
alonswartz Jan 24, 2025
241ef8d
finder: support note preview with lineNumber highlight
alonswartz Jan 26, 2025
028ecae
finder: refine colors for dark and light mode compatibility
alonswartz Jan 26, 2025
82e5bc2
vim: initial notesium.vim with fzf-based integration from readme
alonswartz Jan 29, 2025
42cb624
vim: initial finder and supporting callback functions
alonswartz Jan 29, 2025
597e4cf
vim: list - update to use finder
alonswartz Jan 29, 2025
db08b53
vim: insertlink - update to use finder
alonswartz Jan 29, 2025
d78789b
vim: insertlink - localize autocmd to buffer
alonswartz Jan 29, 2025
8af687e
vim: insertlink - split out command for customizability
alonswartz Jan 29, 2025
b130c77
vim: search - update to use finder
alonswartz Jan 29, 2025
53f136c
vim: search - rename to lines for consistency
alonswartz Jan 29, 2025
feed14a
vim: links - update to use finder
alonswartz Jan 29, 2025
3c8df4f
vim: links - move filename enumeration to command, append if note
alonswartz Jan 29, 2025
841f0ef
vim: links - only append note filename if bang specified and if note
alonswartz Jan 29, 2025
783f0da
vim: config - replace NOTESIUM_WEEKSTART int with g:notesium_weekstar…
alonswartz Jan 29, 2025
00299a1
vim: config - adhere to g:notesium_weekstart in list ctime prefix date
alonswartz Jan 29, 2025
b6239f0
vim: config - add g:notesium_mapping bool to disable default mappings
alonswartz Jan 29, 2025
5697576
vim: removed unneeded command bangs
alonswartz Jan 29, 2025
284908c
vim: web - add windows support via powershell
alonswartz Jan 29, 2025
b23fef7
vim: web - support q-args, append required options if missing
alonswartz Jan 29, 2025
a136246
vim: config - add g:notesium_bin to override default
alonswartz Jan 29, 2025
f633d81
finder: refactor output channel handling to prevent race condition
alonswartz Jan 30, 2025
07aa3ca
vim: insertlink - ensure correct mode transition
alonswartz Feb 2, 2025
2fd11ba
vim: config - refactor NOTESIUM_DIR retrieval into function
alonswartz Feb 2, 2025
885f659
vim: finder - wrap finder functions in neovim check
alonswartz Feb 2, 2025
a49a2ee
vim: finder - add fallback implementation for vim
alonswartz Feb 2, 2025
41dacd0
vim: insertlink - adjust finder window size based on terminal width
alonswartz Feb 2, 2025
935a6c3
vim: config - replace hardcoded window sizes with g:notesium_window
alonswartz Feb 2, 2025
02127c9
vim: restructure for conventional plugin layout
alonswartz Feb 4, 2025
915dc34
readme: replace vim example integration with vim plugin
alonswartz Feb 4, 2025
33077c5
completion: finder end-of-options support
alonswartz Feb 4, 2025
e9adf75
readme: finder command
alonswartz Feb 4, 2025
4b5b949
vim: workaround vimscript max split quirk
alonswartz Feb 5, 2025
6ee7840
vim: added plugin help documentation
alonswartz Feb 6, 2025
bff54f3
readme: update vim section for consistency with plugin help doc
alonswartz Feb 6, 2025
12a318b
vim: ensure notesium_bin is executable, escape file paths
alonswartz Feb 6, 2025
62fe5e7
readme: update vim screenshots using new plugin
alonswartz Feb 6, 2025
768123a
changelog: 0.6.4
alonswartz Feb 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
build/
vim/doc/tags
notesium
67 changes: 67 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,70 @@
## 0.6.4

This release introduces the **finder** command, a built-in interactive
filtering and selection tool powered by the excellent **fzf engine**. It
enhances the CLI with flexible input handling and syntax-highlighted
previews, making it easier to search and navigate notes efficiently. The
finder works great as a standalone tool but becomes even more powerful
when integrated with other tools, such as Vim.

Regarding Vim, Notesium now has a **Vim/Neovim plugin**, replacing the
previous example integration. The new plugin is easier to set up,
removes dependencies on `fzf`, `fzf.vim`, and `bat`, and seamlessly
integrates with the `finder` command. It is more robust, offers greater
flexibility, and enhances compatibility with both Vim and Neovim.

This release **is backwards compatible**, but users transitioning from
the example Vim integration should review the notable changes below and
the updated documentation.

Added:

- Finder: Native interactive filter and selection TUI (embedded `fzf`).
- Finder: Input specified via end-of-options unix convention (`-- CMD [OPTS]`).
- Finder: Input supports List, Links, Links commands and their options.
- Finder: Input default `list --color --prefix=label --sort=alpha`.
- Finder: Preview with syntax highlighting and lineno support (`cat` command).
- Finder: Preview toggle with `Ctrl-/`.
- Finder: Configurable custom prompt.
- Completion: Updated to support Finder end-of-options.

- Cat: Markdown syntax highlighting and concealment.
- Cat: Highlight - `header codeblock code blockquote plainlink listmarker`.
- Cat: Highlight and Concealment - `bold italic markdownlink`.
- Cat: Line number highlight.

- Vim: Brand new Vim/Neovim plugin, installable via plugin managers.
- Vim: Integrates with Finder (removing dependency on `fzf`, `fzf.vim`, `bat`).
- Vim: Supports Neovim floating windows, with fallback for Vim without `term`.
- Vim: Auto enable/disable preview based on terminal width.
- Vim: Auto adjust window size for link-insertion based on terminal width.
- Vim: Documentation accessible via `:help notesium[-section]`.
- Vim: Settings - `g:notesium_(bin|mappings|weekstart|window|window_small)`.
- Vim: Commands - `Notesium(New|Daily|Weekly|List|Links|Lines|Web|InsertLink)`.
- Vim: Mappings - `<Leader>(nn|nd|nw|nl|nm|nc|nk|ns|nW)`, `[[`.

Changed:

- Readme: Updated to include Finder command.
- Readme: Vim example integration replaced with new Vim/Neovim Plugin.
- Readme: Vim screenshots updated using new Vim/Neovim Plugin.

**Vim plugin vs. Vim example integration**:

- Fixed: Links filename enumeration, bang support.
- Fixed: InsertLink autocmd localized to buffer.
- Fixed: InsertLink auto adjust window size based on terminal width.
- Fixed: `<Leader>nc` adheres to g:notesium_weekstart.
- Fixed: NotesiumWeb now supports custom and required arguments.
- Added: NotesiumWeb windows support via powershell.
- Added: g:notesium_bin to override hardcoded assumed `notesium`.
- Added: Callbacks for `editfile` and `insertlink`.
- Added: Plugin documentation accessible via `:help notesium[-section]`.
- Changed: NOTESIUM_WEEKSTART (int) replaced with g:notesium_weekstart (str).
- Changed: NotesiumSearch has been renamed to NotesiumLines.
- Removed: `<Leader>nb` is not included in the plugin mappings.
- Removed: Dependencies on `fzf`, `fzf.vim` or a highlight tool such as `bat`.

## 0.6.3

This release introduces a new **lines** `--filter` option with support
Expand Down
229 changes: 88 additions & 141 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,14 @@ It aspires and is designed to:
- [Section folding](#section-folding)
- [Syntax highlighting and concealment](#syntax-highlighting-and-concealment)
- [Vim](#vim)
- [Example integration](#example-integration)
- [Setup](#setup)
- [Configuration](#configuration)
- [Commands](#commands)
- [Keybindings](#keybindings-1)
- [Fzf search syntax](#fzf-search-syntax)
- [Finder search syntax](#finder-search-syntax)
- [Related Vim settings](#related-vim-settings)
- [Custom URI protocol](#custom-uri-protocol)
- [Example integration](#example-integration-1)
- [Example integration](#example-integration)
- [Handler registration](#handler-registration)
- [Design assumptions and rationale](#design-assumptions-and-rationale)
- [Filenames are 8 hexidecimal digits](#filenames-are-8-hexidecimal-digits)
Expand Down Expand Up @@ -105,6 +107,10 @@ It aspires and is designed to:
- Supports line filtering queries with AND, OR, and NOT conditionals.
- **Stats**
- View counts of notes, labels, orphans, links, lines, words, etc.
- **Finder**
- Interactive filter selection TUI.
- Supports List, Links and Lines commands and their options as input.
- Optional preview window with syntax highlighting and concealment.
- **Web**
- Completely self-contained and runs locally.
- Create and edit notes with web based editor (optional vim-mode).
Expand Down Expand Up @@ -173,29 +179,30 @@ It aspires and is designed to:
<br/>

*[Vim] List: prefixed with associated labels and sorted alphabetically*
![image: vim prefixed label](https://www.notesium.com/images/screenshot-1681733208.png)
![image: vim prefixed label](https://www.notesium.com/images/screenshot-1738853845.png)
<br/>

*[Vim] List: prefixed with modification date and sorted per modification time*
![image: vim prefixed mtime](https://www.notesium.com/images/screenshot-1681733355.png)
![image: vim prefixed mtime](https://www.notesium.com/images/screenshot-1738854202.png)
<br/>

*[Vim] Links: display all links*
![image: vim links all](https://www.notesium.com/images/screenshot-1681733482.png)
![image: vim links all](https://www.notesium.com/images/screenshot-1738854280.png)
<br/>

*[Vim] Links: display links related to the current note*
![image: vim links related](https://www.notesium.com/images/screenshot-1681733712.png)
![image: vim links related](https://www.notesium.com/images/screenshot-1738854409.png)
<br/>

*[Vim] Links: link insertion triggered by `[[`*
![image: vim link insertion](https://www.notesium.com/images/screenshot-1681734183.png)
![image: vim link insertion](https://www.notesium.com/images/screenshot-1738854615.png)
<br/>

*[Vim] Lines: full text search (light theme)*
![image: vim full text search light](https://www.notesium.com/images/screenshot-1681734555.png)
![image: vim full text search light](https://www.notesium.com/images/screenshot-1738854816.png)
<br/>


## CLI

Notesium is primarily tested and supported on Linux, with only
Expand Down Expand Up @@ -289,6 +296,10 @@ Commands:
stats Print statistics
--color Color code using ansi escape sequences
--table Format as table with whitespace delimited columns
finder Start finder (interactive filter selection TUI)
--preview Display note preview (toggle with ctrl-/)
--prompt=STR Set custom prompt text
-- CMD [OPTS] Input (default: list --color --prefix=label --sort=alpha)
web Start web server
--webroot=PATH Path to web root to serve (default: embedded webroot)
--mount=DIR:URI Additional directory to serve under webroot (experimental)
Expand Down Expand Up @@ -511,158 +522,94 @@ of the formatting characters is supported.

## Vim

Notesium does not supply a Vim plugin, it is up to the user to write
their own Vim commands and configure keybindings. That said, below are
some fairly generic commands, with preferences configured in the
keybindings.
Notesium provides a Vim/Neovim plugin that integrates with the Notesium
CLI, particularily the `finder` command providing and interactive filter
selection TUI with syntax highlighted preview.

- Dependencies: [fzf](https://github.com/junegunn/fzf) and [fzf.vim](https://github.com/junegunn/fzf.vim).
- Recommended: [bat](https://github.com/sharkdp/bat) for syntax highlighting in the preview.
- Depends: [notesium](#cli) (0.6.4 or above)
- Recommended: [vim-markdown](https://github.com/preservim/vim-markdown) for general markdown goodness.
- Recommended: [goyo.vim](https://github.com/junegunn/goyo.vim) and [lightlight.vim](https://github.com/junegunn/limelight.vim) for distraction free writing.
- Recommended: [goyo.vim](https://github.com/junegunn/goyo.vim) and [limelight.vim](https://github.com/junegunn/limelight.vim) for distraction free writing.

### Example integration
### Setup

```vim
let $NOTESIUM_DIR = trim(system("notesium home"))
let $NOTESIUM_WEEKSTART = 1 "0 Sunday, 1 Monday, ...

autocmd BufRead,BufNewFile $NOTESIUM_DIR/*.md inoremap <expr> [[ fzf#vim#complete({
\ 'source': 'notesium list --sort=mtime',
\ 'options': '+s -d : --with-nth 3.. --prompt "NotesiumInsertLink> "',
\ 'reducer': {l->"[". split(l[0],':1: ')[1] ."](".split(l[0],':')[0].")"},
\ 'window': {'width': 0.5, 'height': 0.5}})

command! -bang NotesiumNew
\ execute ":e" system("notesium new")

command! -bang NotesiumWeb
\ let s:options = "--stop-on-idle --open-browser" |
\ execute ":silent !nohup notesium web ".s:options." > /dev/null 2>&1 &"

command! -bang -nargs=* NotesiumList
\ let s:spec = {'dir': $NOTESIUM_DIR, 'options': '+s -d : --with-nth 3..'} |
\ call fzf#vim#grep(
\ 'notesium list '.join(map(split(<q-args>), 'shellescape(v:val)'), ' '), 0,
\ &columns > 79 ? fzf#vim#with_preview(s:spec, 'right', 'ctrl-/') : s:spec, <bang>0)

command! -bang -nargs=* NotesiumLinks
\ let s:spec = {'dir': $NOTESIUM_DIR, 'options': '-d : --with-nth 3..'} |
\ call fzf#vim#grep(
\ 'notesium links '.join(map(split(<q-args>), 'shellescape(v:val)'), ' '), 0,
\ &columns > 79 ? fzf#vim#with_preview(s:spec, 'right', 'ctrl-/') : s:spec, <bang>0)

command! -bang -nargs=* NotesiumSearch
\ let s:spec = {'dir': $NOTESIUM_DIR, 'options': '-d : --with-nth 3..'} |
\ call fzf#vim#grep(
\ 'notesium lines '.join(map(split(<q-args>), 'shellescape(v:val)'), ' '), 0,
\ &columns > 79 ? fzf#vim#with_preview(s:spec, 'right', 'ctrl-/') : s:spec, <bang>0)

command! -bang -nargs=* NotesiumDaily
\ let s:cdate = empty(<q-args>) ? strftime('%Y-%m-%d') : <q-args> |
\ let s:output = system('notesium new --verbose --ctime='.s:cdate.'T00:00:00') |
\ let s:filepath = matchstr(s:output, 'path:\zs[^\n]*') |
\ execute 'edit ' . s:filepath |
\ if getline(1) =~ '^\s*$' |
\ let s:epoch = matchstr(s:output, 'epoch:\zs[^\n]*') |
\ call setline(1, '# ' . strftime('%b %d, %Y (%A)', s:epoch)) |
\ endif

command! -bang -nargs=* NotesiumWeekly
\ let s:date = empty(<q-args>) ? strftime('%Y-%m-%d') : <q-args> |
\ let s:output = system('notesium new --verbose --ctime='.s:date.'T00:00:01') |
\ let s:epoch = str2nr(matchstr(s:output, 'epoch:\zs[^\n]*')) |
\ let s:day = strftime('%u', s:epoch) |
\ let s:startOfWeek = empty($NOTESIUM_WEEKSTART) ? 1 : $NOTESIUM_WEEKSTART |
\ let s:diff = (s:day - s:startOfWeek + 7) % 7 |
\ let s:weekBegEpoch = s:epoch - (s:diff * 86400) |
\ let s:weekBegDate = strftime('%Y-%m-%d', s:weekBegEpoch) |
\ let s:output = system('notesium new --verbose --ctime='.s:weekBegDate.'T00:00:01') |
\ let s:filepath = matchstr(s:output, 'path:\zs[^\n]*') |
\ execute 'edit ' . s:filepath |
\ if getline(1) =~ '^\s*$' |
\ let s:weekFmt = s:startOfWeek == 0 ? '%U' : '%V' |
\ let s:yearWeekStr = strftime('%G: Week' . s:weekFmt, s:weekBegEpoch) |
\ let s:weekBegStr = strftime('%a %b %d', s:weekBegEpoch) |
\ let s:weekEndStr = strftime('%a %b %d', s:weekBegEpoch + (6 * 86400)) |
\ let s:title = printf('# %s (%s - %s)', s:yearWeekStr, s:weekBegStr, s:weekEndStr) |
\ call setline(1, s:title) |
\ endif

nnoremap <Leader>nn :NotesiumNew<CR>
nnoremap <Leader>nd :NotesiumDaily<CR>
nnoremap <Leader>nw :NotesiumWeekly<CR>
nnoremap <Leader>nl :NotesiumList --prefix=label --sort=alpha --color<CR>
nnoremap <Leader>nm :NotesiumList --prefix=mtime --sort=mtime --color<CR>
nnoremap <Leader>nc :NotesiumList --prefix=ctime --sort=ctime --color --date=2006-01<CR>
nnoremap <Leader>nb :NotesiumLinks --incoming <C-R>=expand("%:t")<CR><CR>
nnoremap <Leader>nk :NotesiumLinks --color <C-R>=expand("%:t")<CR><CR>
nnoremap <Leader>ns :NotesiumSearch --prefix=title --color<CR>
nnoremap <silent> <Leader>nW :NotesiumWeb<CR>

" overrides for journal
if $NOTESIUM_DIR =~ '**/journal/*'
nnoremap <Leader>nl :NotesiumList --prefix=label --sort=mtime --color<CR>
endif
To install the plugin, add the repository to your plugin manager and
point its runtime path to the `'vim'` directory. For example:

```
" init.vim or .vimrc
Plug 'alonswartz/notesium', { 'rtp': 'vim' }

-- init.lua
Plug('alonswartz/notesium', { ['rtp'] = 'vim' })
```

### Configuration

| Setting | Comment | Default
| ------- | ------- | -------
| `g:notesium_bin` | Binary name or path | `notesium`
| `g:notesium_mappings` | Enable(1) or disable(0) mappings | `1`
| `g:notesium_weekstart` | First day of the week | `monday`
| `g:notesium_window` | Finder Default | `{'width': 0.85, 'height': 0.85}`
| `g:notesium_window_small` | Finder InsertLink | `{'width': 0.50, 'height': 0.50}`

Note: These settings should be set prior to the plugin being sourced.

### Commands

| Command | Comment
| ------- | -------
| `:NotesiumNew` | Open new note for editing
| `:NotesiumDaily [YYYY-MM-DD]` | Open new or existing daily note
| `:NotesiumWeekly [YYYY-MM-DD]` | Open new or existing weekly note
| `:NotesiumList [LIST_OPTS]` | Open finder: list of notes
| `:NotesiumLines [LINES_OPTS]` | Open finder: lines of all notes
| `:NotesiumLinks [LINKS_OPTS]` | Open finder: links of all notes
| `:NotesiumLinks! [LINKS_OPTS]` | Open finder: links of the active note
| `:NotesiumInsertLink [LIST_OPTS]` | Open finder: insert selection as markdown link
| `:NotesiumWeb [WEB_OPTS]` | Start web server, open browser (stop on idle)

Note: `NotesiumWeekly` depends on `g:notesium_weekstart`.

### Keybindings

| Mode | Binding | Comment
| ---- | ------- | -------
| insert | `[[` | Opens note list, insert selection as markdown formatted link
| normal | `<Leader>nn` | Opens new note for editing
| normal | `<Leader>nd` | Opens new or existing daily note
| normal | `<Leader>nw` | Opens new or existing weekly note
| normal | `<Leader>nl` | List with prefixed label, sorted alphabetically (mtime if journal)
| normal | `<Leader>nm` | List with prefixed date modified, sorted by mtime
| normal | `<Leader>nc` | List with prefixed date created in custom format, sorted by ctime
| normal | `<Leader>nb` | List all notes linking to this note (backlinks)
| normal | `<Leader>nk` | List all links related to this note
| normal | `<Leader>ns` | Full text search
| normal | `<Leader>nW` | Opens browser with web view (auto stop webserver on idle)
| fzf | `C-k` `C-j` | Move up and down in fzf window
| fzf | `Enter` | Open selection
| fzf | `C-t` `C-x` `C-v` | Open selection in new tab, split, vertical split
| fzf | `C-/` | Toggle preview
| fzf | `Shift-Tab` | Multiple selection
| normal | `ge` | Open the link under the cursor (vim-markdown)
| normal | `[[` `]]` | Jump back and forward between headings (vim-markdown)

### Fzf search syntax
| Mode | Binding | Comment
| ---- | ------- | -------
| insert | `[[` | Opens note list, insert selection as markdown formatted link
| normal | `<Leader>nn` | Opens new note for editing
| normal | `<Leader>nd` | Opens new or existing daily note
| normal | `<Leader>nw` | Opens new or existing weekly note
| normal | `<Leader>nl` | List with prefixed label, sorted alphabetically; mtime if journal
| normal | `<Leader>nm` | List with prefixed date modified, sorted by mtime
| normal | `<Leader>nc` | List with prefixed date created `(YYYY/WeekXX)`, sorted by ctime
| normal | `<Leader>nk` | List all links related to active note (or all if none)
| normal | `<Leader>ns` | Full text search with prefixed note title
| normal | `<Leader>nW` | Opens browser with embedded web/app (auto stop webserver on idle)
| finder | `C-j` `↓` | Select next entry (down)
| finder | `C-k` `↑` | Select previous entry (up)
| finder | `C-/` | Toggle preview
| finder | `Enter` | Submit selected entry
| finder | `Esc` | Dismiss finder
| normal | `ge` | Open the link under the cursor (vim-markdown)
| normal | `[[` `]]` | Jump back and forward between headings (vim-markdown)

### Finder search syntax

| Token | Match Type | Comment
| ----- | ---------- | -------
| `sbtrkt` | fuzzy-match | Items that fuzzy match `sbtrkt`
| `'word` | exact-match | Items that include `word`
| `word` | exact-match | Items that include `word`
| `^word` | prefix exact-match | Items that start with `word`
| `word$` | suffix exact-match | Items that end with `word`
| `!word` | inverse exact-match | Items that do not include `word`
| `!^word` | inverse prefix exact-match | Items that do not start with `word`
| `!word$` | inverse suffix exact-match | Items that do not end with `word`
| `foo bar` | multiple exact match (AND) | Items that include both `foo` AND `bar`
| `foo \| bar` | multiple exact match (OR) | Items that include either `foo` OR `bar`
| `'sbtrkt` | fuzzy-match | Items that fuzzy match `sbtrkt`

### Related Vim settings

```vim
" junegunn/fzf.vim
let $FZF_DEFAULT_OPTS="--reverse --filepath-word --no-separator --no-scrollbar "
let g:fzf_buffers_jump = 1
let g:fzf_layout = { 'window': { 'width': 0.85, 'height': 0.85 } }
let g:fzf_colors = {
\ 'fg': ['fg', 'Normal'],
\ 'bg': ['bg', 'Normal'],
\ 'hl': ['fg', 'Comment'],
\ 'fg+': ['fg', 'CursorLine', 'CursorColumn', 'Normal'],
\ 'bg+': ['bg', 'CursorLine', 'CursorColumn'],
\ 'hl+': ['fg', 'Statement'],
\ 'info': ['fg', 'PreProc'],
\ 'pointer': ['fg', 'Exception'],
\ 'marker': ['fg', 'Keyword'],
\ 'spinner': ['fg', 'Label'],
\ 'header': ['fg', 'Comment'] }

" preservim/vim-markdown
let g:vim_markdown_folding_style_pythonic = 1
let g:vim_markdown_folding_level = 2
Expand All @@ -671,9 +618,9 @@ let g:vim_markdown_auto_insert_bullets = 0
let g:vim_markdown_new_list_item_indent = 0
let g:vim_markdown_toc_autofit = 1
let g:vim_markdown_conceal_code_blocks = 0

let g:markdown_fenced_languages = ['json', 'sh', 'shell=bash']
hi def link mkdHeading htmlH1

autocmd FileType markdown setlocal conceallevel=2
```

Expand Down Expand Up @@ -874,4 +821,4 @@ PAUSE=y bats tests/list.bats --tap

The MIT License (MIT)

Copyright (c) 2023-2024 Alon Swartz
Copyright (c) 2023-2025 Alon Swartz
Loading