Link to latest releases automatically
Yes! You're already using it. GitHub provides automatic "latest" redirects:
https://github.com/HelgeSverre/token/releases/latest/download/{asset-name}
This URL pattern automatically redirects to the latest release's asset. Your website already uses this for the curl commands (e.g., token-darwin-arm64.tar.gz).
For direct download buttons, you can use the same pattern:
<a href="https://github.com/HelgeSverre/token/releases/latest/download/token-darwin-arm64.tar.gz">
Download for macOS (Apple Silicon)
</a>
The only requirement is that the asset filenames must be consistent across releases. Your GitHub Actions workflow should already handle this if it names artifacts the same way each time.
Done. The website now has a dedicated download section with 4 clickable download cards:
- macOS Apple Silicon (.tar.gz)
- macOS Intel (.tar.gz)
- Linux x86_64 (.tar.gz)
- Windows x86_64 (.zip)
Each card links to https://github.com/HelgeSverre/token/releases/latest/download/{artifact} which automatically redirects to the latest release. The filenames now match your CI artifact names (token-macos-aarch64, token-macos-x86_64, etc.).
Done. The changes:
- Logo - Now just text "Token" without any icon
- Download cards - Each has the appropriate platform icon:
- Apple logo for macOS (both variants)
- Tux (Linux penguin) for Linux
- Windows logo for Windows
- Icons are muted gray by default and turn accent color on hover
Done - switched the Linux icon to a clean terminal/command prompt icon (chevron + underscore) which is universally recognized and looks crisp at any size.
Deployed to https://token-editor.com
Good benchmark setup. Let me run the benchmarks to establish a baseline and identify bottlenecks:
Interesting findings. The realistic_typing_with_newlines benchmark is very slow (~845ms for 10 lines). Let me also run rendering benchmarks and then do some flamegraph profiling:
Now let's do CPU profiling with samply (or cargo-flamegraph) to identify specific hot spots:
Let me look at the editable system to understand what might be causing performance issues:
Let me look at the update functions that handle text editing to see where the bottleneck might be:
The benchmark is taking too long. Let me look at the rendering path and the update_document function, which might have the bottleneck:
I see several potential bottlenecks. Let me look at schedule_syntax_parse and ensure_cursor_visible which are called after every edit:
Now let me check the benchmark support file to understand what the benchmarks actually test:
Let me look at some hot path functions like word_start_before and word_end_after which collect entire slices to strings:
There are the major bottlenecks. Lines 31-32 and 56-57 in word_start_before and word_end_after allocate entire document slices just to iterate over characters.
Let me also check the ensure_cursor_visible function:
Let me look at the RopeBuffer line function which also allocates:
Now I have a clear picture. Let me document the findings:
Summary
I've completed a comprehensive performance analysis. The main findings are documented in docs/performance-analysis.md.
Key bottlenecks identified:
word_start_before/word_end_afterinsrc/update/document.rs- allocates entire document prefix/suffix as String just to iterate charactersRopeBuffer::line()- double allocation (to_string + trim)move_word_left/rightin EditableState - collects line chars into Veclast_non_whitespace_column- unnecessary string collection
Benchmark highlights:
realistic_typing_with_newlines: 845ms for 10 lines (major bottleneck)- ~297 allocations per line typed
- Insert operations take ~3.2µs per char, but word operations are much slower
The performance issues are primarily allocation-heavy hot paths, not algorithmic complexity. Fixing these with iterator-based approaches should yield significant improvements.