Skip to content

basalt/v0.12.3

Choose a tag to compare

@erikjuhani erikjuhani released this 10 Mar 21:52
d0e075d

There are two bigger changes in this release.

  1. Vim-mode, that allows similar movement as with vim-like editors (vim, helix). However the functionality is very limited at the moment.
    • G and gg were added and you can move between words using b and w in Normal mode.
    • You can enable vim mode by adding vim_mode = true to basalt config. More info in the vim-mode section.

basalt-0-12-3-vim

  1. Creating new notes and folders. All notes and folders are created as Untitled. Sub directory folder creation is not yet supported. You can create notes with n when explorer pane is selected and folders with N. You can rename the notes or folders with r.

basalt-0-12-3-create

Additionally I squashed a few bugs here and there. You can check the Changelog for more details.

0.12.3 (Mar, 10 2026)

Added

This change adds support for a sequence (or chord) of keys like 'gg' or
'bn' or 'gth'.

The keys maps are separated into Single keys (which can contain
modifiers) or a 'sequence' of keys called Chord.

Additionally added support for uppercased chars in key bindings, which
means that users can now use shift + char to run commands.

Organized and structured the key code parsing, so it's more readable and
the 'special' cases are clearly represented.

This commit adds key sequence handling to basalt, which means that users
can create key bindings with a key sequence like gg or ciw.

  • Replace single-key lookup with pending_keys: Vec<Keystroke> on
    AppState, handle_event and handle_key_event take &mut AppState
    to drive accumulation and prefix/exact matching
  • Add ConfigSection::sequence_to_message and is_sequence_prefix
  • Remove old key_to_message / handle_active_component_event, editing
    bypass is now inlined in handle_key_event
  • handle_editing_event in input and note_editor now take KeyEvent by
    value for consistency

Related to #400
Related to #212

Adds ScrollToTop/ScrollToBottom to the note editor and explorer message
enums, wired through new command variants: note_editor_scroll_to_top,
note_editor_scroll_to_bottom, explorer_scroll_to_top,
explorer_scroll_to_bottom.

Note editor ScrollToBottom uses cursor_jump to the last block rather
than cursor_down(usize::MAX), which silently does nothing because
saturating_add clamps to usize::MAX and skip(lines.len()) exhausts the
iterator.

When vim_mode = true in the user config, a vim.toml preset is merged
between the base config and the user config, so users can still override
individual bindings. The preset adds:

  • ctrl+f / ctrl+b for half-page scrolling in note editor, explorer,
    and help modal (replacing ctrl+d / ctrl+u)
  • gg / G for jump to top/bottom in note editor, explorer, and outline

Add Normal/Insert sub-modes within EDIT mode. i enters Insert mode,
Esc returns to Normal for hjkl navigation, Esc again exits to READ.

Fix block navigation in edit mode: track editing_block explicitly to
prevent layout oscillation, commit text_buffer before switching blocks,
fix modified() after block switch, and use AST source ranges for
correct cursor positioning when entering code blocks.

  • 687ab46 Add create untitled note and folder commands

Bind n to create a new untitled note and N to create a new
untitled folder in the explorer. Both commands select the newly
created item in the explorer after creation.

Changed

  • 0c9883c Replace default keybindings with vim preset when vim_mode is enabled by @erikjuhani

Instead of merging vim.toml bindings on top of the defaults, vim mode
now replaces the entire key_bindings set for each section it defines.
This ensures vim-style bindings like gg and G are the only way to
scroll to top/bottom, without leftover default bindings like
ctrl+shift+up/down.

Some terminals send 'g'+SHIFT instead of 'G'+SHIFT. Normalize this in
Keystroke::from so key bindings match regardless of terminal behavior.
Also fix From<&KeyEvent> to go through the normalization path.

Fixed

Fix inverted vim_mode condition that loaded vim config when disabled...

Add w/b word motion bindings for input modal in vim.toml and rename
VIM_CONFIG_STR to VIM_CONFIGURATION_STR for consistency

  • cda1b25 Fix cursor movement skipping blocks with no accessible content lines by @erikjuhani

When moving up/down, if the target line has no content (e.g. a synthetic
line in a visual code block), search in the opposite direction as a
fallback. This fixes ScrollToTop not working when the first element is a
code block, and ScrollToBottom not reaching the last line.

  • ef9f76d Fix first line not rendering in edit mode and vim save

When entering edit mode before layout, enter_insert couldn't find
blocks and created a spurious empty paragraph node, hiding the real
first line. Guard the empty-node fallback to only fire for genuinely
empty files.

Also commit the text buffer when exiting vim insert mode so that save
writes the updated content.

  • fea931b Fix Explorer lexicographical order in item sorting

When you had items with number suffixes like 1, 2, 3, 100, the standard
rust comparison and ordering would not work as expected, as users are
usually expecting natural ordering. What happened was that we received:
"item 1, item 10, item 2" instead of "item 1, item 2, item 10".

Added natord crate for natural sort ordering, and now explorer sorts the
items in expected order "item 1, item 2, and item 10".

  • e80e4e2 Fix faulty app state after renaming

In some conditions after rename the state would be left in "limbo" and
"frozen" state, which meant that users could not navigate normally
anymore. This happened because we didn't correctly change to Explorer
pane after exiting from rename input.

  • d7fb1c5 Fix stale rendering after exiting vim insert mode

When using vim mode with NORMAL and INSERT modes, when creating writing
new nodes for example a heading and then exiting would result in visual
bug that appeared as if the current node merged with the next one, e.g.
a paragraph after our newly created heading looked liked it was merged
into it.

Fixed the visual bug by accessing the ast_nodes directly, since
virtual_document in this case would have "stale" data.