claude-code icon indicating copy to clipboard operation
claude-code copied to clipboard

Ctrl+Backspace and Ctrl+Arrow navigation issues with Cyrillic text

Open MR-SOME-HOPE opened this issue 5 months ago • 13 comments

When working with Cyrillic (Unicode) text in Claude Code interactive mode, word-based keyboard shortcuts don't work correctly:

  1. Ctrl+Backspace - deletes the entire Cyrillic line instead of just the last word
  2. Ctrl+← / Ctrl+→ - jumps to the beginning/end of the entire line instead of moving between words

With Latin characters, both shortcuts work correctly:

  • Ctrl+Backspace deletes only the last word
  • Ctrl+Arrow keys navigate word by word

Expected behavior:

  • Ctrl+Backspace should delete only the last Cyrillic word
  • Ctrl+Arrow keys should navigate between Cyrillic words

Actual behavior:

  • Ctrl+Backspace deletes the entire Cyrillic line
  • Ctrl+Arrow keys jump to line start/end

Environment: Windows 11, WLS

MR-SOME-HOPE avatar Jul 05 '25 10:07 MR-SOME-HOPE

Is it reproducing on macOS in any terminal I tried (ghostty, wezterm, goland, vscode).

How to reproduce:

Copy and paste to the Claude code terminal some cyrillic text, e.g.:

Добро пожаловать в Википедию, свободную энциклопедию, которую может редактировать каждый.

And try to navigate over it using Ctrl+← / Ctrl+→ . It will jump from the beginning to the end of the whole text and backwards.

Expected behavior

It should jump over words, as it does for English text like this:

Welcome to Wikipedia, the free encyclopedia that anyone can edit.

theyoprst avatar Jul 11 '25 15:07 theyoprst

#1943

Kolger avatar Aug 12 '25 21:08 Kolger

Do you know if we have any plans for this issue? It happens for a lot of non-English languages (Ukrainian, Bulgarian, etc)

it-sha avatar Aug 30 '25 08:08 it-sha

Same thing with Alt-left and Alt-right - can't jump between Cyrillic words

ro31337 avatar Oct 11 '25 16:10 ro31337

@chrislloyd is there any chance this can get fixed please? Has been happening for quite a while, international users are suffering. All other similar TUI tools (OpenCode, etc) work fine. I think it might be regular expression fix.

ro31337 avatar Oct 11 '25 16:10 ro31337

Workaround

The issue is in isOverWordChar() method using ASCII-only /\w/ regex.

One-line fix:

CLI_FILE=$(echo ~/.nvm/versions/node/v*/lib/node_modules/@anthropic-ai/claude-code/cli.js) && perl -i.backup -pe 's|return/\\w/\.test\(A\)\}isOverWhitespace\(\)|return/[\\p{L}\\p{N}_]/u.test(A)}isOverWhitespace()|' "$CLI_FILE"

Then restart claude.

To restore:

CLI_FILE=$(echo ~/.nvm/versions/node/v*/lib/node_modules/@anthropic-ai/claude-code/cli.js) && cp "$CLI_FILE.backup" "$CLI_FILE"

What changed: /\w//[\p{L}\p{N}_]/u (Unicode-aware word boundaries)

Tested on Linux, Claude Code v2.0.22. Works with Cyrillic, should work with any Unicode text.

⚠️ Note: Will be overwritten on Claude Code updates.

ShadowOfLoony avatar Oct 18 '25 20:10 ShadowOfLoony

@ShadowOfLoony tried that, I thought I'd let you know about "No such file or directory":

CLI_FILE=$(echo ~/.nvm/versions/node/v*/lib/node_modules/@anthropic-ai/claude-code/cli.js) && perl -i.backup -pe 's|return/\\w/\.test\(A\)\}isOverWhitespace\(\)|return/[\\p{L}\\p{N}_]/u.test(A)}isOverWhitespace()|' "$CLI_FILE"
Can't open /home/user/.nvm/versions/node/v18.20.8/lib/node_modules/@anthropic-ai/claude-code/cli.js /home/user/.nvm/versions/node/v22.17.0/lib/node_modules/@anthropic-ai/claude-code/cli.js: No such file or directory.
➜  app git:(main) ✗ claude -v
2.0.22 (Claude Code)
➜  app git:(main) ✗ echo ~/.nvm/versions/node/v*/lib/node_modules/@anthropic-ai/claude-code/cli.js
/home/user/.nvm/versions/node/v18.20.8/lib/node_modules/@anthropic-ai/claude-code/cli.js /home/user/.nvm/versions/node/v22.17.0/lib/node_modules/@anthropic-ai/claude-code/cli.js
➜  app git:(main) uname -a
Linux PC 6.6.87.1-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Mon Apr 21 17:08:54 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux

The issue appears to be is when you have multiple Node versions, echo returns multiple space-separated paths, and perl tries to open them as a single filename (which doesn't exist).

ro31337 avatar Oct 18 '25 20:10 ro31337

Here is improved version, stand-alone script:

#!/bin/bash

# Find the Claude Code CLI file(s)
CLI_FILES=(~/.nvm/versions/node/v*/lib/node_modules/@anthropic-ai/claude-code/cli.js)

# Check if any files were found
if [ ${#CLI_FILES[@]} -eq 0 ] || [ ! -f "${CLI_FILES[0]}" ]; then
    echo "Error: No Claude Code CLI files found"
    exit 1
fi

echo "Found ${#CLI_FILES[@]} Claude Code installation(s)"
echo ""

PATCHED_COUNT=0
SKIPPED_COUNT=0

# Apply the fix to each file
for CLI_FILE in "${CLI_FILES[@]}"; do
    if [ -f "$CLI_FILE" ]; then
        # Check if already patched
        if grep -q 'return/\[\\p{L}\\p{N}_\]/u\.test(A)}isOverWhitespace()' "$CLI_FILE"; then
            echo "⊘ Already patched: $CLI_FILE"
            ((SKIPPED_COUNT++))
        else
            echo "→ Patching: $CLI_FILE"

            # Create backup only if it doesn't exist
            if [ ! -f "$CLI_FILE.backup" ]; then
                cp "$CLI_FILE" "$CLI_FILE.backup"
                echo "  Created backup: $CLI_FILE.backup"
            else
                echo "  Using existing backup: $CLI_FILE.backup"
            fi

            # Apply the Unicode word boundary fix
            perl -i -pe 's|return/\\w/\.test\(A\)\}isOverWhitespace\(\)|return/[\\p{L}\\p{N}_]/u.test(A)}isOverWhitespace()|' "$CLI_FILE"

            echo "  ✓ Patched successfully"
            ((PATCHED_COUNT++))
        fi
        echo ""
    fi
done

echo "════════════════════════════════════════════════════════════════"
echo "Summary: $PATCHED_COUNT patched, $SKIPPED_COUNT already patched"
echo "════════════════════════════════════════════════════════════════"

if [ $PATCHED_COUNT -gt 0 ]; then
    echo ""
    echo "⚠ Please restart Claude Code for changes to take effect!"
fi

echo ""
echo "To restore original version, run:"
for CLI_FILE in "${CLI_FILES[@]}"; do
    if [ -f "$CLI_FILE.backup" ]; then
        echo "  cp \"$CLI_FILE.backup\" \"$CLI_FILE\""
    fi
done

ro31337 avatar Oct 18 '25 20:10 ro31337

Add mise version manager support, the same script, but slightly improved:

#!/bin/bash

# Find the Claude Code CLI file(s) in different possible locations
CLI_FILES=()

# Check NVM installations
for file in ~/.nvm/versions/node/v*/lib/node_modules/@anthropic-ai/claude-code/cli.js; do
    [ -f "$file" ] && CLI_FILES+=("$file")
done

# Check mise installations
for file in ~/.local/share/mise/installs/node/*/lib/node_modules/@anthropic-ai/claude-code/cli.js; do
    [ -f "$file" ] && CLI_FILES+=("$file")
done

# Check if any files were found
if [ ${#CLI_FILES[@]} -eq 0 ]; then
    echo "Error: No Claude Code CLI files found"
    echo ""
    echo "Searched in:"
    echo "  - ~/.nvm/versions/node/*/lib/node_modules/@anthropic-ai/claude-code/cli.js"
    echo "  - ~/.local/share/mise/installs/node/*/lib/node_modules/@anthropic-ai/claude-code/cli.js"
    exit 1
fi

echo "Found ${#CLI_FILES[@]} Claude Code installation(s)"
echo ""

PATCHED_COUNT=0
SKIPPED_COUNT=0

# Apply the fix to each file
for CLI_FILE in "${CLI_FILES[@]}"; do
    if [ -f "$CLI_FILE" ]; then
        # Check if already patched
        if grep -q 'return/\[\\p{L}\\p{N}_\]/u\.test(A)}isOverWhitespace()' "$CLI_FILE"; then
            echo "⊘ Already patched: $CLI_FILE"
            ((SKIPPED_COUNT++))
        else
            echo "→ Patching: $CLI_FILE"

            # Create backup only if it doesn't exist
            if [ ! -f "$CLI_FILE.backup" ]; then
                cp "$CLI_FILE" "$CLI_FILE.backup"
                echo "  Created backup: $CLI_FILE.backup"
            else
                echo "  Using existing backup: $CLI_FILE.backup"
            fi

            # Apply the Unicode word boundary fix
            perl -i -pe 's|return/\\w/\.test\(A\)\}isOverWhitespace\(\)|return/[\\p{L}\\p{N}_]/u.test(A)}isOverWhitespace()|' "$CLI_FILE"

            echo "  ✓ Patched successfully"
            ((PATCHED_COUNT++))
        fi
        echo ""
    fi
done

echo "════════════════════════════════════════════════════════════════"
echo "Summary: $PATCHED_COUNT patched, $SKIPPED_COUNT already patched"
echo "════════════════════════════════════════════════════════════════"

if [ $PATCHED_COUNT -gt 0 ]; then
    echo ""
    echo "⚠ Please restart Claude Code for changes to take effect!"
fi

echo ""
echo "To restore original version, run:"
for CLI_FILE in "${CLI_FILES[@]}"; do
    if [ -f "$CLI_FILE.backup" ]; then
        echo "  cp \"$CLI_FILE.backup\" \"$CLI_FILE\""
    fi
done

romanlarridin avatar Oct 24 '25 17:10 romanlarridin

This issue has been inactive for 30 days. If the issue is still occurring, please comment to let us know. Otherwise, this issue will be automatically closed in 30 days for housekeeping purposes.

github-actions[bot] avatar Dec 10 '25 10:12 github-actions[bot]

Still not fixed. Do not close.

roboxdev avatar Dec 10 '25 10:12 roboxdev

This issue still remains. For example, with CC v2.0.62 under WSL installed by npm:

  1. Type lon-Latin text (e.g. in Ukrainian "Доброго ранку")
  2. press Alt+arrow. See that cursor is moved to text begin/end instead of one word
  3. press Ctrl+Backspace. The whole text is deleted instead of one word

it-sha avatar Dec 11 '25 06:12 it-sha

I contacted them on X, and afterwards they closed my issue #1943.

So I believe they’ve fixed it, and I hope it will be included in the next release.

Kolger avatar Dec 11 '25 10:12 Kolger

@cirospaciari Thank you for fixing the Alt+arrow issue

Ctrl+Backspace issue still remains in v2.0.67

Steps to reproduce:

  1. Type or paste non-Latin text (e.g., in Ukrainian "Доброго ранку")
  2. Press Ctrl+Backspace. The last letter is deleted instead of one word

UPDATE: Probably the same regression for Latin text as well

it-sha avatar Dec 12 '25 09:12 it-sha

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.

github-actions[bot] avatar Dec 19 '25 14:12 github-actions[bot]