- Commit: 97467f8
- File:
src/script-detection.ts(NEW) - Features:
- Unicode range detection for Arabic, Syriac, N'Ko
- Context-aware detection for neutral characters
- Excludes Arabic punctuation (comma, semicolon, etc.)
- Spaces/whitespace always treated as word boundaries
- Commit: 1b68e0a
- File:
src/word-boundary.ts(NEW) - Features:
- Finds connected Arabic word boundaries
- Simple algorithm: stops at non-Arabic characters
- Performance: ±50 character search range
- Commit: a26c13a
- File:
src/block-cursor.ts(MODIFIED) - Features:
- Latin text (focused): opaque cursor with visible text ✅ TESTED
- Arabic text (focused): transparent cursor ✅ TESTED
- Unfocused: outline cursor for both
- Files modified:
src/block-cursor.ts- major changessrc/script-detection.ts- punctuation refinements
- Status: WORKING AND TESTED ✅
- Last build: 18:22 (Nov 10)
What changed:
- Refined Arabic punctuation detection to exclude only word breakers
- Diacritics (U+064B-U+065F) now correctly treated as part of letters
- Spaces/whitespace explicitly excluded from connected script detection
Key code:
// Spaces and whitespace should NEVER be treated as connected script
if (char === ' ' || char === '\t' || char === '\n' || char === '\r') {
return { type: ScriptType.LATIN, requiresSpecialCursor: false, isConnectedScript: false };
}
// Arabic punctuation (word breakers only)
const isArabicPunctuation = codePoint === 0x060C || // comma
codePoint === 0x061B || // semicolon
codePoint === 0x061F || // question mark
codePoint === 0x06D4 || // full stop
// ... etcMajor changes:
a) Added CursorLayerType enum:
enum CursorLayerType {
STANDARD = 'standard',
ARABIC_WORD = 'arabic_word',
ARABIC_CHAR = 'arabic_char'
}b) Extended Piece class:
- Added
layerTypeparameter (optional, defaults to STANDARD) - Updated
eq()method to compare layerType
c) Modified readPos():
- Changed to spread pieces array:
cursors.push(...pieces) - Handles multiple pieces per cursor
d) Changed measureCursor() return type:
- From:
Piece | null - To:
Piece[] | null - Returns array of pieces (enables multi-layer rendering)
e) Added measureArabicDualCursor() function (NEW):
- Finds word boundaries using
findArabicWordBoundaries() - Measures word block coordinates
- Creates two Piece objects:
- Word-level block (semi-transparent pink background)
- Character-level outline (white 1px box-shadow)
- Returns
[wordPiece, charPiece]
f) Updated CSS theme:
- Restored original focused cursor:
background: "#ff9696" - Added
.cm-cursor-arabic-wordstyles:- Semi-transparent background:
rgba(255, 150, 150, 0.3) - z-index: 1
- Semi-transparent background:
- Added
.cm-cursor-arabic-charstyles:- White outline:
boxShadow: "0 0 0 1px #ffffff" - Transparent background
- z-index: 2
- White outline:
- Unfocused state hides character outline
g) Decision logic in measureCursor():
if (scriptDetection.requiresSpecialCursor && isFocused) {
return measureArabicDualCursor(...);
} else {
return [new Piece(..., CursorLayerType.STANDARD)];
}src/block-cursor.tsimportsfindArabicWordBoundariesfrom./word-boundary
Tested with mixed Latin/Arabic text:
- ✅ Latin "Hello world": White text visible in cursor (opaque)
- ✅ Arabic letters: Transparent cursor + dual-cursor when focused
- ✅ Arabic punctuation (comma): Standard cursor (not dual)
- ✅ Spaces: Standard cursor (not dual)
- ✅ Word boundaries: Correctly detected at script transitions
- ✅ Navigation (h/j/k/l): Dual cursor tracks correctly through Arabic words
- ✅ No skipped characters
git add src/block-cursor.ts src/script-detection.ts
git commit -m "feat: Implement dual-cursor for Arabic/connected scripts
Implements Phase 4 of the dual-cursor system architecture.
This adds hierarchical dual-cursor rendering for Arabic text:
- Word-level block: Semi-transparent pink background covering entire connected word
- Character-level outline: White 1px outline on specific letter under cursor
Changes:
- Add CursorLayerType enum for different cursor rendering strategies
- Extend Piece class with layerType parameter
- Modify measureCursor() to return Piece[] for multi-layer rendering
- Add measureArabicDualCursor() function for dual-layer measurement
- Update CSS theme with Arabic-specific cursor styles
- Refine script detection to exclude only punctuation (not diacritics)
- Ensure spaces/whitespace always treated as word boundaries
Visual design:
- Focused Arabic: Semi-transparent pink word block + white char outline
- Focused Latin: Solid pink block with white text (opaque)
- Unfocused: Pink outline for both (character outline hidden for Arabic)
Performance: Word boundary detection O(n) where n ≤ 100 characters
Tested: ✅ Dual-cursor renders correctly on Arabic text
Tested: ✅ Word boundaries respect punctuation and spaces
Tested: ✅ Navigation (hjkl) tracks correctly through Arabic words
Related to replit/codemirror-vim#248"# The tsconfig.json changes are already in place (uncommitted)
# Just need to commit them at the end
git add tsconfig.json
git commit -m "feat: Add workspace paths configuration for TypeScript
Configures TypeScript paths to resolve @codemirror/* from parent
node_modules, enabling proper workspace package resolution.
This allows building the vim plugin as a workspace package in the
parent Zettlr repository."- Build:
npm run build - Test in Zettlr with Arabic + Latin mixed text
- Verify all cursor behaviors still work
cd /Users/orwa/repos/Zettlr-official
git add packages/codemirror-vim
git commit -m "chore: Update vim plugin submodule to dual-cursor implementation"src/script-detection.ts✅ COMMITTEDsrc/word-boundary.ts✅ COMMITTED
src/block-cursor.ts- Phase 4 dual-cursor implementationsrc/script-detection.ts- Punctuation refinementstsconfig.json- Workspace paths (for local dev only)
dist/index.js- Built successfully (18:22)dist/index.cjs- Built successfully
None - all testing passed ✅
- tsconfig.json paths configuration is for LOCAL DEVELOPMENT ONLY
- Do not commit tsconfig.json to upstream PR
- Type declaration errors can be ignored (JS build succeeds)