rdenadai/improvements-v0.0.2 #2

Open
rdenadai wants to merge 63 commits from rdenadai/improvements-v0.0.2 into main
Owner
No description provided.
- Add theme module with 4 built-in themes: One Dark Pro, Dracula, Monokai Pro, Catppuccin Mocha
- Replace all hardcoded colors in editor.slint and main.slint with theme properties
- Add command palette modal (Ctrl+P) with search filtering
- Wire theme switching: palette -> Rust -> Slint color properties + syntax colors
- Persist selected theme to config (settings.json)
- Default theme: One Dark Pro
- Fix calc-line: use floor instead of round for accurate line hit-testing
- Fix calc-col: clamp to valid range with proper rounding
- Add double-click timeout (400ms Timer) replacing fragile click-count
- Throttle drag updates: only update selection when line/col changes
- Current-line highlight now reactive (line-idx == cursor-line) in Slint
- Remove refresh_styled_lines from click/selection/double-click handlers
- Optimize select_word_at: use byte-level iteration instead of Vec<char>
- Use floor(x / char-width) instead of round(x / char-width - 0.5)
- Clicking anywhere within a character cell now places cursor at that column
- round(x / char-width) places cursor at nearest character boundary
- Left half of char -> cursor before it, right half -> cursor after it
- Before first char shows Col 0, on first char shows Col 1, etc.
- Line remains 1-indexed (Ln 1 for first line)
- Clicking anywhere on a character places cursor at its left edge
- Fixes inability to position cursor before first character on a line
- Selection now highlights only the selected characters, not entire lines
- Selection overlay positioned using char-width * column offsets
- Current-line highlight suppressed only on lines with active selection
- Normalized selection direction (start <= end) for consistent rendering
- Removed unused is-in-selection function
Selection highlighting is now embedded in styled text spans instead of
using absolute-positioned overlays. Each StyledSegment has a 'selected'
field, and spans are split at selection column boundaries during
build_styled_lines. This eliminates char-width accumulation errors that
caused selection highlighting to drift by 2-3px over long lines.

- Add split_segments_for_selection() for column-accurate span splitting
- Add selection-drag callback for real-time selection during mouse drag
- Refresh styled lines on click (clear), drag (update), and double-click
- Add get_normalized_selection() helper for extracting selection state
- Add max-column field to EditorConfig (default: 120)
- Display vertical ruler line at max-column position
- Implement auto-wrap on space when exceeding max-column
- Increase cursor width from 2px to 3px for better visibility
Remove double-counted viewport offsets (flick.viewport-x/y) from cursor
rectangle. Since the cursor is a child of the Flickable, scrolling is
already applied automatically. Also remove unused cursor-measure Text
element and fix indentation.
- Cursor clamping: Route mouse drag events through Rust callback
  (cursor-drag) for proper column clamping to line length. Prevents
  cursor from being positioned beyond the last character.

- Horizontal scroll: ensure_cursor_visible now handles both vertical
  and horizontal scrolling to keep cursor in view.

- Soft word-wrap: Lines exceeding max_column are visually split into
  multiple display lines at word boundaries. Adds visual cursor
  positioning (cursor-visual-line/col) separate from logical position.
  Gutter hides line numbers for continuation lines. Selection overlay
  accounts for logical column offsets.

- Visual-to-logical coordinate conversion for mouse events (click,
  drag, double-click) to handle wrapped line mapping correctly.
Cursor clamping:
- set_cursor_position() now takes a buffer ref and always clamps
  line to [0, total_lines-1] and column to [0, line_len]. This is
  the single authoritative cursor setter (Zed/VSCode pattern).
- Eliminated all direct window.set_cursor_line/set_cursor_column
  calls across keyboard.rs, mouse.rs, clipboard.rs, file.rs, tabs.rs.
- Removed standalone clamp_column_to_line() — clamping is built-in.

Syntax highlighting:
- Skip tree-sitter nodes inside ERROR ancestors — their highlight
  boundaries are unreliable and cause valid code to change colors.
- Normalize overlapping spans: when multiple spans cover the same
  byte range, keep the narrowest (most specific) match.
- Sort spans by start position, then by width descending, before
  normalization to ensure correct specificity ordering.
Always set cursor to (0,0) when opening a file or switching tabs.
Previously, opening a file set cursor to line index 1 (visual line 2).
- Call update_cursor_display() after set_cursor_position(0, 0) on
  file open and tab switch. Previously cursor-visual-line/col stayed
  stale from the previous file, causing the cursor to render at the
  wrong line despite status bar showing Ln 1, Col 0.

- Add cursor_width config (settings.json: cursor_width, default 2.0).
  Maps to EditorConfig.cursor-width in Slint, controlling cursor
  thickness. Configurable from 1px (thin) to any desired width.
- File > Configuration opens ~/.config/ehwaz/settings.json in the
  editor as a regular tab (creates the file if it doesn't exist).
- When saving settings.json, the editor automatically detects it's
  the config file and reloads: font, max_column, cursor_width,
  theme, and re-highlights the current file.
- Status bar shows 'Configuration saved and reloaded' on config save.
- Replace col * char-width with cursor-pos-measurer Text element that
  measures actual cursor-text-before string width for pixel-perfect cursor X
- Handle soft-wrap: cursor-text-before now uses visual line segment text
  instead of full logical line, ensuring correct position on wrapped lines
- Add opacity (0.5) for wide cursors (> 3px) so text remains visible
- Update ensure_cursor_visible horizontal scroll to use measured offset
- Add cursor-text-before change handler to trigger scroll following
Move cursor Rectangle from standalone position (after text in z-order)
into each line's code area, declared BEFORE the text HorizontalLayout.
This ensures text renders ON TOP of the cursor, so wide/block cursors
show the cursor color as a background highlight while keeping syntax-
colored text fully visible.

The cursor X position uses cursor-x-offset (measured from cursor-pos-
measurer Text element) for pixel-accurate alignment with the rendered
text, regardless of font metrics rounding.
This pull request can be merged automatically.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin rdenadai/improvements-v0.0.2:rdenadai/improvements-v0.0.2
git switch rdenadai/improvements-v0.0.2

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff rdenadai/improvements-v0.0.2
git switch rdenadai/improvements-v0.0.2
git rebase main
git switch main
git merge --ff-only rdenadai/improvements-v0.0.2
git switch rdenadai/improvements-v0.0.2
git rebase main
git switch main
git merge --no-ff rdenadai/improvements-v0.0.2
git switch main
git merge --squash rdenadai/improvements-v0.0.2
git switch main
git merge --ff-only rdenadai/improvements-v0.0.2
git switch main
git merge rdenadai/improvements-v0.0.2
git push origin main
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
rdenadai/ehwaz!2
No description provided.