google-gemini / google-gemini/gemini-cli

Reverse search highlights the wrong substring when a history entry contains a character whose lowercase form is longer (e.g. İ)

Open Beginner friendly
#29,302 2 comments 0 reactions 0 assignees View on GitHub
area/core effort/small status/bot-triaged
Dominant language
TypeScript
Stars
107k
Forks
14.6k
Avg merge
2d 3h
Merged PRs (30d)
45

Description

### What happened?

Reverse search (Ctrl+R history search) can highlight the wrong substring. `useReverseSearchCompletion` computes `matchedIndex` against the *lowercased* command, but `ExpandableText` applies that index to the *original-case* label.

In `packages/cli/src/ui/hooks/useReverseSearchCompletion.ts` (lines 76-78 at revision `9c1b0a610`):

```ts
const idx = cmd.toLowerCase().indexOf(query);
if (idx !== -1) {
out.push({ label: cmd, value: cmd, matchedIndex: idx });
}
```

Most lowercasing is length-preserving, so the two indexes coincide. However, some characters change UTF-16 length when lowercased — notably `İ` (U+0130), which lowercases to two code units (`i` + U+0307). Every index after such a character is shifted by one in the lowercased copy, so the highlight lands one position too late.

Repro:

```js
const cmd = 'echo İ abc';
const query = 'abc';
const matchedIndex = cmd.toLowerCase().indexOf(query); // 8 — index into "echo i̇ abc"
cmd.slice(matchedIndex, matchedIndex + query.length); // "bc" — wrong highlight target
// 'abc' actually starts at index 7 in the original cmd
```

Component-level confirmation: rendering `SuggestionsDisplay` in reverse mode with exactly the values the hook produces for history entry `echo İ abc` and query `abc` renders the line `echo İ abc` with the inverse-video highlight on `bc` instead of `abc`.

### What did you expect to happen?

The highlight should cover the matched substring in the displayed (original-case) string — here `abc`.

### Client information

Component-level reproduction; no Gemini API request, login session, or account is involved. Verified against a working tree based on main revision `9c1b0a610534d6f8120964cf2672c07807d8fc90`; `useReverseSearchCompletion.tsx` is unmodified from that revision. Package version reports `0.61.0-nightly.20260908.gc647533d6`.

### Login information

Not applicable. No provider, API key, Google account, or network request is used by the reproducer.

### Anything else we need to know?

A fix would compute the match index against the original string (for example a case-insensitive search on `cmd` itself) instead of reusing an index from the lowercased copy, since `matchedIndex` is consumed as a UTF-16 offset into the original label. Cosmetic severity: the highlight is display-only — selection inserts the full `value`, so nothing beyond the highlight position is affected.

Contributor guide

Open the contributing guide

Research direction

Start in packages/cli/src/ui/hooks/useReverseSearchCompletion.ts at the matching logic around lines 76-78, then inspect how matchedIndex is consumed by ExpandableText and SuggestionsDisplay. Reproduce the reverse search case with `echo İ abc` and query `abc`; done when the highlight covers the original-case match and the component-level reproduction passes without changing selection behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
86/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.