Starting OpenIDEA with a file showed the last session's tabs without the file: restoring the saved tabs counted as the user activating another tab, so the pending open of the launched file was dropped as superseded. Restoring a session no longer counts as an activation; the launched file opens next to the restored tabs and becomes active (also for a file opened with its project at startup).
Ruff is now an external formatter for Python next to the Ruff language server: Settings › Languages & Frameworks › Ruff has the executable path, a configuration directory (or file), the provider preference, enabled languages, run-on-save, and Reformat with Ruff. Formatting runs on the unsaved document through stdin (with Ruff's --range for selections, in 1-based code-point columns) and never writes the file first. The configuration directory is shared with Ruff LSP, which can then start without a root marker. Tools that can't format a language are rejected even when requested.
Co-authored-by: muutot <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Language smoke / Language smoke (kotlin) (push) Failing after 5s
Language smoke / Language smoke (go) (push) Failing after 7s
Language smoke / Language smoke (java) (push) Failing after 6s
Language smoke / Language smoke (python) (push) Failing after 4s
Language smoke / Language smoke (rust) (push) Failing after 5s
Language smoke / Language smoke (typescript) (push) Failing after 4s
CI / Plugins (SDK, official, fixtures) (push) Successful in 3m8s
CI / Cargo deny (push) Successful in 56s
CI / Remote server (linux musl) (push) Successful in 5m57s
CI / E2E (push) Failing after 15m56s
CI / Frontend (push) Failing after 24m3s
CI / Rust (ubuntu-22.04) (push) Failing after 46m51s
CI / Rust (macos-latest) (push) Canceled after 0s
CI / Rust (windows-latest) (push) Canceled after 0s
Python defaults diverged in several places: built-ins used the predefined magenta, __init__/__doc__ used function/self colours, instance fields the property colour, f-strings and byte strings the generic string colour, and the PEP 695 type keyword was uncoloured. Python now has its own tokens for built-ins, predefined definitions/usages, f-strings and byte strings; instance fields follow identifiers; type is a keyword. Unused parameters (not reported by Pyrefly) are greyed by a scope-aware local check that skips self/cls/_ names and signatures dictated elsewhere: stubs, @abstractmethod/@overload/@override, dunder methods and methods of classes with bases.
Co-authored-by: muutot <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
.log files rendered as plain text: the log language had no ui-mode and CodeMirror ships no log grammar. A lightweight Log stream mode now colours severity levels (upper case anywhere, any case only when marked: [warn], <Info>, level=error), timestamps, exception names, URLs and stack frames, reusing scheme colours; WARN uses the UI warning colour.
Closes#1541
Co-authored-by: jaw52 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* fix(editor): keep selections whole over line backgrounds and indent guides
Multi-line selections could show a 1px seam between their stacked
rectangles, indent guides showed as short dashes inside a selection,
and a breakpoint or execution line hid the selection past its text.
- Snap selection rectangle edges to device pixels so stacked pieces
share one edge.
- Paint caret-row, breakpoint and execution line backgrounds on a
pseudo-element below the selection layer.
- Draw indent guides on a pseudo-element above the text.
* test(e2e): check the visible selection layer in the theme flow
When the backend rejects an edit for any reason other than a stale version, the editor replaces its unsaved text with the file's content, but the reason was only printed to the webview console. The backend now logs the rejected edit with its path, and the editor writes the sync error and the discarded edits to the log file, so reports of edits that roll back (#1530, #1522) can be diagnosed from the log.
Python files got semantic colours only once the language server answered, and locals, globals, instance and class attributes, constants, properties and type parameters all looked the same. A highlighter on the Lezer syntax tree now colours them right away in PyCharm's finer categories (also self, builtins, decorators, definitions, method calls, brackets); LSP semantic tokens stay authoritative when they arrive. The categories are new --syn-python-* theme tokens wired through the built-in themes and Harbor Night, and PyCharm .icls schemes import their PY.* attributes.
Co-authored-by: muutot <[email protected]>
The diff and merge viewers had no overview lane, so changes outside the viewport were invisible. The scrollbar now marks every change, coloured by type (modified, inserted, deleted, conflict), in the side-by-side view (both panes), the aligned view (one stripe over the shared scroller), the unified view and the three-way merge editor; clicking a mark jumps to the change. Marks span the lane's width from the first to the last changed line with a 2px minimum. The colours are new --diff-*-stripe theme tokens (Darcula, Light and High-contrast values), mapped from ERROR_STRIPE_COLOR on .icls import and set in the Harbor Night theme template.
Part of #1505
Co-authored-by: jaw52 <[email protected]>
Copy Reference on a call site now resolves the method through Go to Definition and copies its qualified name (crate::Inventory::add in Rust, the dotted module path in Python, and so on); positions without an unambiguous method target copy the project-relative path and line, as before. The clipboard write starts during the key press with a ClipboardItem whose text resolves later, because WebKit rejects a write started after the asynchronous lookup; without ClipboardItem it writes plain text once known. Python module paths also drop everything up to the last src/ directory, for monorepo layouts.
Co-authored-by: zzxzz12345 <[email protected]>
On macOS a force click on an identifier opened the system Look Up popover instead of navigating, and the popover appeared over any text in the UI, because the webview never handled WebKit's force-touch events. The input dispatcher now cancels webkitmouseforcewillbegin in every window, and the editor treats an unmodified webkitmouseforcedown like a Cmd-click (Go to Declaration or Usages). Look Up via three-finger tap or Ctrl-Cmd-D still works.
Co-authored-by: lleviathe <[email protected]>
Copy Reference used the outline symbols enclosing the caret, so anywhere inside a method it copied the method's qualified name and the line was lost. It now names a symbol only with the caret on a declaration's name (its selection range) and copies `path:line` everywhere else, for every language. The `package …;` symbol jdtls reports is no longer qualified, so that line copies `path:1`.
Co-authored-by: jaw52 <[email protected]>
In some YAML files over about a kilobyte, a mapping that follows comment lines
lost its highlighting from the second comment to the end of the mapping. The
YAML parser (@lezer/yaml with @lezer/lr) can give that mapping node an inverted
range when it falls on a tree buffer boundary (1024 entries by default), and
highlighting skips the whole node. The YAML mode now parses into buffers of
65536 entries, so ordinary YAML files stay in one buffer and never hit the
boundary.
Refs #809
Importing a PhpStorm .icls applied Java/Kotlin keys and PHP-only colours to every language, so PHP variables, strings and punctuation came out wrong. Java, Kotlin and PHP attributes are now kept per language (Color Scheme lists them under their own nodes, and editors scope them by data-language), explicit attribute inheritance is resolved, an explicit TextAttributes value resets omitted bold/italic, the light/dark parent follows the scheme's background, and PHP classes, method declarations, fields, brackets and separators get their own tags. Selecting a language attribute in Settings previews that language's colours.
Co-authored-by: marianomd <[email protected]>
The selection is drawn in a layer behind the text, so any range with its own background (find
matches, warnings in light schemes, usages, semantic backgrounds) hid it: selected text there
kept its yellow or other highlight. Selected text is now also marked in the innermost span with
the selection colour, in text editors, notebook cells and the VCS viewers.
The overview lane sat over the scrollbar with pointer-events: none and is 12px wide, the native scrollbar 10px: a press on the lane's edge, or where marks covered the thumb, reached the text layer and dragged a text selection instead of scrolling. The lane now owns the vertical scrollbar, as IntelliJ's error stripe does: the native one is hidden, the lane's thumb drags (with the same geometry it is drawn with), and a press above or below the thumb pages the editor. Marks still jump to their line.
Co-authored-by: IsGuibo <[email protected]>
Document::diff only trimmed the common prefix and suffix, so two distant
edits on disk became one change spanning everything between them. The
caret and scroll position inside that span were mapped to its start,
which made the editor jump to the first edit after an agent, formatter
or git operation rewrote the file.
Diff the changed middle line by line (Myers via similar, 50 ms deadline
with a coarser fallback) and emit one change per edited region, trimmed
to its differing characters. The frontend DocSync path produces the same
per-region changes, so external reloads, local history restores and
formatting keep the caret and view in place.
Closes#1326
Co-authored-by: ntbang0901 <[email protected]>
lua-language-server marks globals with the `global` token modifier, but
the editor dropped it, so a global variable looked like a local unless
rainbow highlighting was on. The modifier now sets `cm-sem-global`, drawn
in a new Language Defaults › Identifiers › Global variable colour
(`--syn-global`): library globals keep the predefined colour and calls the
function-call colour. Imported IntelliJ themes and .icls schemes take it
from DEFAULT_GLOBAL_VARIABLE. Built-in schemes default it to the local
variable colour (IntelliJ's fallback for the key), so they look as before
until a scheme sets it.
Fixes#1370
The Find / Replace in Files popup gets the popup surface and spacing,
the match count and empty states ("Clear option(s)"), the footer with
"Open results in new tab", a resizable popup with a remembered results /
preview split, file mask suggestions from the project's file types
(new index_file_extensions), mnemonics and inline icons. Shortcuts are
spelled for the platform: Linux showed macOS glyphs in the popup, the
shared SearchField, the find bars and Search Everywhere. Replace keeps
its Preview diff.
Closes#1219
Co-authored-by: fuqiuluo <[email protected]>
Git Log could lose commits when filtering by several paths, draw wrong
ancestry after filtering or collapsing rows, and open the wrong
repository in multi-root views. The graph is now projected over the full
commit DAG and laid out in Bek order, so filtered and collapsed views keep
the real ancestry; each log view keeps its own filters and requests.
Commit metadata, messages and path changes are kept in a persistent index
(by object id, in the IDE's cache directory) with seekable paging, and the
log gains parent-aware merge comparisons, a lazy revision browser,
read-only logs of repositories outside the project (opened with command
execution disabled), commit bookmarks, configurable built-in columns and
batched commit details. The adapted IntelliJ algorithms are attributed in
THIRD_PARTY_LICENSES.md.
Closes#872
Co-authored-by: shohruh-genius <[email protected]>
Lines with a color literal show a swatch of the (first) color in the
gutter: `#rgb` / `#rrggbb` with or without alpha, `rgb()` / `rgba()` /
`hsl()` / `hsla()`, and CSS named colors in property values of style
sheets. Outside style sheets and markup only quoted hex values and color
functions count, so `#123` issue numbers and `#add` comments get none;
prose files get none at all.
Clicking a swatch in an editable file opens the system color picker; the
picked color replaces the literal in its own format (hex case and length,
the function's name and separators, the original alpha), as one undoable
edit per pick. Settings › Editor › General › Gutter Icons › Color preview
turns the swatches off.
Fixes#1206
Go to Declaration and modifier-click on a fragment-only Markdown or HTML link such as [artist::order](#Artist-order) said there was nothing to go to: the text-reference fallback rejected fragment-only targets, and Markdown fragment lookup checked headings only, never HTML id / name anchors. Fragment-only href targets are now recognized and resolve in the same file (the current buffer, so unsaved anchors count), and Markdown files fall back to id / name anchors after headings.
Co-authored-by: pravdomil <[email protected]>
The editor's Copy / Paste Special submenu only had Copy Path and Paste from History, so a class's fully qualified name couldn't be copied from the context menu although Copy Reference exists as an action. It now lists Copy Reference, Paste as Plain Text and Paste from History; the file path stays in the editor tab's Copy Path/Reference menu.
Fixes#1261
The read-only previews beside Problems, Show Usages and TODO results are syntax-coloured from one whole-file parse (capped for very large files), so a line inside a block comment or a multi-line string is coloured as such; the pane renders plain first and recolours when the parse lands. SourcePreview takes the colouring as a colorize prop (the editor's previewColors), keeping src/ui free of editor imports, and the tok-* colours live once in global.css instead of a copy per view, with the theme's comment style.
Co-authored-by: qtvbwfn <[email protected]>
Markdown from comments, hovers, agent replies and files renders into the IDE's own document, so a raw <style> restyled the whole IDE and <form> / style= reached the page. Every Markdown sanitizer (LSP hovers and comments, agent messages, Markdown preview) now forbids <style>, <form> and the style attribute; agent messages also drop data-* written in a reply, since their click handlers trust data-copy / data-path. align, width and <details> stay.
Closes#1319
Co-authored-by: ntbang0901 <[email protected]>
Switching tabs remounts the editor view and the marker cache lived in its plugin; focusing an editor dropped the cache too. So every visit re-ran an implementation search per declaration in view, and on jdtls each one walks the whole workspace (#879: java at ~40% CPU while moving between classes). Answers are now cached per file and dropped only when other files change (edits, or source changes on disk; build output ignored) or a language server settles, through one window-wide subscription whose echo guard survives remounts.
Fixes#879
Git › Show History for Selection, as in IDEA: from Git › Current File and the editor's Git menu it opens a tab with only the commits that changed the selected lines (or the caret line), newest first, and the block before and after each commit in the diff viewer. Only Show History for the whole file existed before. git log -L tracks the lines across renames; the selection is first mapped through unsaved and uncommitted edits to HEAD's lines, and those edits come first as Local Changes. The query is its own ide-vcs module and cancellable command (vcs_block_history), read-only and allowed in Restricted Mode (--no-ext-diff --no-textconv).
Co-authored-by: ldg030201 <[email protected]>
The find bar belonged to the pane and every bar shared one query, and its effect re-ran the search and moved the caret whenever the active tab changed, so switching files dragged the previous file's search into the next one and lost its caret. Each tab now has its own find bar with its own query and options, as with IDEA's per-editor search session. The last search only pre-fills a newly opened bar (or the selection does) and drives Find Next without a bar; showing a bar again only highlights, and the caret moves only when the query or an option changes in that bar. Bars of closed tabs are dropped.
Co-authored-by: jaw52 <[email protected]>
On WebKit, CodeMirror positions tooltips absolutely inside the editor, but the tooltip space still reported the whole window as the right bound. CodeMirror never shifted a tooltip near the editor's right edge to the left, the box was squeezed into the space left of that edge, and the next measurement read the squeezed width, so it could end as a one-character column. The tooltip space is now the editor's own horizontal extent (clamped to the window) and tooltips size to their content, which fixes hover, inline blame, debugger values, signature help and hints together.
Co-authored-by: ntbang0901 <[email protected]>
"Show pinned tabs in a separate row" was ignored while "Multiple rows" was on, because the pinned row explicitly excluded horizontal layouts with multiple rows. The two options are independent, so the pinned row now shows whenever some but not all tabs are pinned, and each row wraps on its own. With the rows split, dropping a tab on the pinned row pins it and keeps it in the pinned group, and dropping it on the other row unpins it.
Co-authored-by: ntbang0901 <[email protected]>
Scroll containers set cursor: text, and the webview applies an element's cursor to its scrollbar, so scrollbars showed the I-beam. The containers now keep the arrow and the text inside them gets the I-beam: the editor (.cm-content instead of .cm-scroller, which also covers the diff and merge editors), the source preview, the Run, Build and Debugger consoles, the Git console, the Database output and the Services log.
Co-authored-by: ppxb <[email protected]>
Opening a popup (intentions, completion) moved focus out of the editor and
autosaved it. The save cleanup could change the text, such as trailing
spaces on another line, so the quick fix the popup listed no longer matched
and the first attempt to apply it failed.
While focus is in a popup the editor is not saved; it is saved when focus
moves on from the popup to anything but the editor.
jdtls still completes and navigates JDK classes in a non-project file such
as a scratch; it only skips semantic checks and project classes. The banner
said navigation and completion don't work, and in a Maven or Gradle project
it offered a build reload that can't bring a file outside the project in.
- The banner now says only syntax errors are reported and only JDK classes
resolve.
- The Maven / Gradle reload is offered only for files inside the open
project (or one of its workspace projects).
Refactor | Pull Members Up… and Push Members Down… for Java, from the Refactor menu, the editor context menu and Refactor This. A dialog picks the destination and the members (Make abstract / Keep abstract); problems are confirmed before anything changes; the edit is applied as one change or previewed first.
JDT LS offers neither as a code action, so the app-owned JDT LS bundle (plugins/java-usages 1.3.0) adds two delegate commands that run JDT's PullUpRefactoringProcessor / PushDownRefactoringProcessor and return the problems and the edit without applying it, exposed as lsp_hierarchy_members / lsp_hierarchy_refactor (also over the remote host dispatcher). The bundled jar was rebuilt from source with JDT LS 1.63.0 and matches the recorded SHA-256.
Co-authored-by: fhrmrk <[email protected]>
Icon themes could only map files by exact name or extension and folders by name. Themes can now match by regular expression or path (patterns that could backtrack badly, lookaround, inline flags and named groups are refused at install), ship dark variants, replace built-in UI and symbol (PSI) icons, and offer packs (groups) and variants (choices). A theme describes its own options page in Settings › Plugins as sections of items naming options the IDE implements (hide file/folder/UI/PSI icons, hollow folders, accent, monochrome, saturation, opacity, icon size, row height); values are stored per theme in appearance.fileIconThemeOptions. Existing themes are unchanged.
Closes#1096
Co-authored-by: pdasilem <[email protected]>
When the project change after an authorized leave never came, the editors' close decision stayed authorized: files failed with "The project is closing" and later leaves with "An editor close decision is already pending" until restart. An authorized decision with no project opening is now released when the window opens a file or is left again.
Fixes#1139
Sync with Deployed opens in its own window, one per project window. It lists local files next to the server's copies, with filters, content and binary comparison, and an embedded side-by-side diff whose local side can be edited. The selected file can be synchronized (Enter) without closing the window.
The window is the `deployment` kind of the auxiliary windows that Settings and comparisons use. A cancelled close in it stops its project window from closing. The preview uses the vcs diff viewer through its `diff` editor kind. Also covers #811 (compare with the deployed versions).
Co-authored-by: marianomd <[email protected]>
Since #1100 a theme that turns light or dark switches a chosen scheme of the other kind back to the theme's own. It did so also when the scheme was chosen in the same Apply as the theme, so One Light + Solarized Dark left the default light editor. A scheme set by the settings change that also changes the theme now goes with it; a later theme change on its own still switches it back.
Closes#1136
Co-authored-by: fhrmrk <[email protected]>
The TODO preview is an editor on the file, as in IntelliJ: a CodeMirror view attached to the real document, so edits share the buffer with editor tabs and Save All saves them; no editing switch. The caret lands on the selected item, also when another item of the same file is selected. Read-only files fall back to the read-only preview. Dirty buffers are held rather than released (releasing would auto-save or drop the edits), and previewText reads the held text.
Co-authored-by: qtvbwfn <[email protected]>
Smart Step Into and Safe Delete tested the text before a match with /[\p{L}\p{N}_$]$/u, which V8 in Node 26 fails for a letter outside the BMP (a lone property class before $), so smartStep.test.ts failed. Both checks now use an alternation with the same meaning.
Switching the IDE theme kept an explicitly chosen editor color scheme, so a light theme could keep a dark editor. When the applied theme turns light or dark, a chosen scheme of the other kind now switches back to the theme's own; a scheme picked to go with the current theme is kept. Reacts to the applied theme, so Quick Switch, Settings, Welcome › Customize, other windows and Sync with OS are all covered.
Without a running language server (none configured for the language, or not installed, stopped or crashed), the editor showed no syntax errors at all, though the built-in parser already finds them. The editor now reports the parser's errors for such files, checked again after edits and when a language server starts or stops; while a server runs for the language it reports syntax errors itself. SQL is left to the database support. The check is the built-in Syntax errors inspection.
Fixes#824
Error, warning, weak-warning and typo underlines never showed on macOS, nor did underline effects of syntax tokens from a colour scheme: WebKit rejects a text-decoration shorthand with a style or colour (underline wavy <colour>), so the declaration fell back to none.
The editor's diagnostic and token styles also set -webkit-text-decoration, which WebKit takes the full value through; the red wavy underlines of the Problems, Build, Project and Database views use the longhand properties.
A plugin system built on WebAssembly components (wasmtime, WASI p2), with a
typed WIT API (`openidea:[email protected]`) and a Rust SDK, shipped as a preview.
- Extension points declared in `plugin.toml` (commands, languages, themes,
icon themes, menus, key bindings, status items, settings, views, custom
editors, file icons and templates, run detectors, editor providers),
validated before anything takes effect and projected onto the workbench's
own registries: plugin themes and file icon themes are chosen in
Settings › Appearance and Quick Switch, plugin shortcuts are edited in
Settings › Keymap, plugin problems are grouped in Settings › Inspections.
- Capabilities with risk levels and consent at install, pinned `process:`
programs, secrets in the OS keychain.
- Runtime: one thread per active plugin, fuel/time/memory budgets, soft and
hard deadlines on the editing path, cancellation, crash backoff, idle
reclaim, a precompiled-component cache; remote projects run code plugins on
`openidea-server`.
- Web views and custom editors with a sandboxed page, a document bridge
joined to the text editor's undo history, and split or preview layouts.
- Distribution: signed `.oiplugin` packages, a static marketplace index with
revocation, versioned installs with rollback, install from a `.zip` or a
folder. The release workflow signs and publishes the official plugins and
their index, which released builds use as the default marketplace.
- Official plugins: String Tools, Key Promoter, Git Toolbox, AI Completion,
Checkstyle, MyBatis Navigator, CSV Editor, Solidity, Material Icons, Harbor
Night, Excalidraw, Graphviz, Regex Tester, License Header.
Closes#732
Co-authored-by: Deng Liu <[email protected]>
Co-authored-by: florentvdry <[email protected]>
codemirror-vim only discards single-character IME commits in Normal mode, so multi-character commits (Chinese pinyin, Japanese conversions) were written into the document and could replace the selection. In Normal/Visual mode the composition now renders as usual and its whole span is restored when it ends; an ASCII single-character commit (dead keys) is replayed as a Vim key. Composition changes are marked transientChange: they stay out of undo history, the document model, the backend and other split panes. Insert/Replace mode is unchanged.
Closes#1056
Co-authored-by: xtr-hub <[email protected]>
Dragging a tab showed no floating copy: the ghost cloned the tab's classes, and .tab { position: relative } loaded after .ghost { position: fixed }. The ghost is now positioned inline, and a tab dragged within its strip stays as an empty slot the other tabs move around; the insertion line for tabs from another strip is drawn inside the edge tabs so the scroller doesn't clip it. A terminal group is now a drop target like an editor pane: the middle joins the group, an edge splits off a new group (dropZoneAt moves to ui and is shared).
Closes#1052
Co-authored-by: fuqiuluo <[email protected]>
oxfmt ran only below an oxfmt configuration and reused the Prettier settings. It now has its own settings group and page (path, enabled languages, formatting provider, run on save) next to Prettier. For a language with an external formatter, oxfmt formats it when enabled for that language and either an oxfmt configuration is found above the file or oxfmt is the selected provider; otherwise Prettier, when enabled. Turning Prettier off for a language still leaves it to the language server. New Reformat with Prettier / Reformat with oxfmt commands run that tool regardless of the settings and report languages it cannot format.
Co-authored-by: d0whc3r <[email protected]>
The result pane starts from the base and every change, conflicting or not, gets Accept / Ignore next to its side; accepting one side of a conflict still lets the other side be appended, and the modifier key resolves using that side directly. Adds Resolve Simple Conflicts (word-level), Apply Non-Conflicting Changes from the left, right or both (optionally on opening), Revert Conflict Resolution, Accept Yours / Accept Theirs / Cancel / Apply, Compare Contents between any two versions, and undo back to the conflicted state. CRLF and UTF-16 files are written back exactly, deleted sides and binary files are handled, and the commands are registered as merge.* actions.
Refs #826
Co-authored-by: ntbang0901 <[email protected]>
In Preview only the editor is display:none and the preview only followed it in the split layout, so Structure's Autoscroll to Source moved a hidden caret and Autoscroll from Source never saw the preview scroll. Caret moves without an edit now scroll a Preview-only preview to that line, and the preview publishes the source line on screen through editor/api (setShownLine/useShownLine) so Structure selects the heading being read; it is cleared when the editor comes back or the preview closes.
Fixes#977
Co-authored-by: jaw52 <[email protected]>
jdtls only checks the syntax of a Java file outside every module's source
folders (or outside any imported project) and answers navigation with
nothing. The editor then said only "Cannot find declaration to go to", and
the server's explanation was a warning squiggle on line 1.
- A banner above the editor explains it while the server reports it, for
jdtls (not on the classpath of a project / non-project file), gopls (no
package, build constraints — this replaces the Go-only banner) and
rust-analyzer (unlinked file). For Java it offers the Maven / Gradle reload
when available.
- Go to Declaration / Implementation / Type Declaration that finds nothing
in such a file gives the reason in its hint.
Fixes#827
The overview lane lies over the vertical scrollbar, so a mark the height of the lane (a new file added to git is one green VCS mark) hid the native thumb completely. The lane now draws the thumb itself, above its marks and without taking the pointer, at the position of the native one (scrollbarThumb, inset by its 2px border); it switches to the hover color while the pointer is on the thumb. The native thumb is made transparent in editors that have the lane, so the two don't add up, and still takes the drag. Editors without the lane (notebook cells, previews) keep the native thumb.
Fixes#1014
Co-authored-by: Claude Opus 5.5 <[email protected]>