From cc258e36bae02e655c338016660a2dd1ea6c8185 Mon Sep 17 00:00:00 2001 From: "ADA (OpenClaw Agent)" Date: Tue, 22 Sep 2026 15:42:47 +0200 Subject: [PATCH] fix: restore visible text selection --- CHANGELOG.md | 13 ++++++++++++- package-lock.json | 4 ++-- package.json | 2 +- src-tauri/Cargo.lock | 2 +- src-tauri/Cargo.toml | 2 +- src-tauri/tauri.conf.json | 2 +- src/editor.ts | 9 +++++++++ src/theme.ts | 14 +++++++++++--- 8 files changed, 38 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9696e3f..a307146 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,16 @@ and the project uses [Semantic Versioning](https://semver.org/). - Automatic updates — the updater plugin and keys must be bundled, so this has to be decided before the first release that should support it +## [0.6.1] — 2026-09-22 + +### Fixed +- **Mouse, keyboard and Vim selections are reliably visible on every line.** + The opaque active-line highlight previously covered CodeMirror's selection + layer, making a drag within the current line appear broken even though the + text was selected. Rui now removes that covering highlight while a selection + exists and enforces a clear selection/background contrast in light, dark and + imported Omarchy themes. + ## [0.6.0] — 2026-09-04 ### Changed @@ -970,7 +980,8 @@ Erste Veröffentlichung. - Builds sind unsigniert, SmartScreen warnt beim ersten Start - Sinnvolle Dateigrösse bei rund 25 MB gedeckelt -[Unveröffentlicht]: https://github.com/jli-software/Rui/compare/v0.6.0...HEAD +[Unveröffentlicht]: https://github.com/jli-software/Rui/compare/v0.6.1...HEAD +[0.6.1]: https://github.com/jli-software/Rui/compare/v0.6.0...v0.6.1 [0.6.0]: https://github.com/jli-software/Rui/compare/v0.5.4...v0.6.0 [0.5.4]: https://github.com/jli-software/Rui/compare/v0.5.3...v0.5.4 [0.5.3]: https://github.com/jli-software/Rui/compare/v0.5.2...v0.5.3 diff --git a/package-lock.json b/package-lock.json index caee19a..5b96adb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "rui", - "version": "0.6.0", + "version": "0.6.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rui", - "version": "0.6.0", + "version": "0.6.1", "license": "MIT", "dependencies": { "@codemirror/autocomplete": "^6.20.3", diff --git a/package.json b/package.json index b1a8cd7..1af9e4e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "rui", "private": true, - "version": "0.6.0", + "version": "0.6.1", "description": "A lean text editor for snippets and notes", "license": "MIT", "author": "Jonas Gaiching", diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index b4b5d65..068992b 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -3108,7 +3108,7 @@ dependencies = [ [[package]] name = "rui" -version = "0.6.0" +version = "0.6.1" dependencies = [ "chardetng", "chrono", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index a77d4c7..29804c4 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rui" -version = "0.6.0" +version = "0.6.1" description = "A lean text editor for snippets and notes" authors = ["Jonas Gaiching"] edition = "2021" diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 9b7fe1f..da2d0f2 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "Rui", - "version": "0.6.0", + "version": "0.6.1", "identifier": "ch.gaiching.rui", "build": { "beforeDevCommand": "npm run dev", diff --git a/src/editor.ts b/src/editor.ts index a4000be..b4c8c64 100644 --- a/src/editor.ts +++ b/src/editor.ts @@ -112,6 +112,15 @@ export class RuiEditor { // nichts mitläuft, das dieser Editor nicht braucht. history(), drawSelection(), + // The active-line background lives in the document layer, while + // CodeMirror draws selections behind it. Mark non-empty selections + // on the editor root so the theme can stop the active line from + // covering a same-line mouse or Vim selection. + EditorView.editorAttributes.of((view) => ({ + class: view.state.selection.ranges.some((range) => !range.empty) + ? "cm-has-selection" + : "", + })), dropCursor(), rectangularSelection(), crosshairCursor(), diff --git a/src/theme.ts b/src/theme.ts index e0ab208..9193064 100644 --- a/src/theme.ts +++ b/src/theme.ts @@ -388,6 +388,10 @@ function highlightStyle(p: Palette) { /** Erzeugt das komplette CodeMirror-Theme aus einer Palette. */ export function editorTheme(p: Palette, dark: boolean): Extension { + // CodeMirror's drawn selection is a layer behind the document. Keep the + // colour visibly distinct even when an imported palette provides a shade + // too close to the editor background. + const selection = ensureContrast(p.selection, p.bg, 2, p.text); const view = EditorView.theme( { "&": { @@ -405,9 +409,13 @@ export function editorTheme(p: Palette, dark: boolean): Extension { }, "&.cm-focused .cm-selectionBackgroundPrimary, .cm-selectionBackground, .cm-content ::selection": { - backgroundColor: `${p.selection} !important`, + backgroundColor: `${selection} !important`, }, ".cm-activeLine": { backgroundColor: p.activeLine }, + // `.cm-activeLine` is part of the content layer and therefore covers + // CodeMirror's selection layer when both are opaque. That made a drag + // confined to the active line look as if no selection had happened. + "&.cm-has-selection .cm-activeLine": { backgroundColor: "transparent" }, ".cm-gutters": { backgroundColor: p.bg, color: p.gutter, @@ -430,9 +438,9 @@ export function editorTheme(p: Palette, dark: boolean): Extension { outline: `1px solid ${p.accent}`, }, ".cm-nonmatchingBracket": { color: p.danger }, - ".cm-selectionMatch": { backgroundColor: p.selection }, + ".cm-selectionMatch": { backgroundColor: selection }, ".cm-searchMatch": { - backgroundColor: p.selection, + backgroundColor: selection, outline: `1px solid ${p.border}`, }, ".cm-searchMatch.cm-searchMatch-selected": {