Vimcraft Docs / vim.cursor - Cursor Rendering API
vim.cursor - Cursor Rendering API
Control cursor position and visual rendering. Designed for animated cursor plugins like smear-cursor.
Getting Position
getPosition()
Get the current logical cursor position.
const { row, col } = vim.cursor.getPosition(); console.log(`Cursor at row ${row}, column ${col}`); // Both row and col are 0-indexed
Render Override
Override the visual cursor position without changing the logical position. Essential for smooth cursor animations.
setRenderPosition(row, col)
Set where the cursor appears visually.
// Display cursor at row 5, column 10 (visual only) vim.cursor.setRenderPosition(5, 10); // The actual cursor position remains unchanged const actual = vim.cursor.getPosition(); // actual might be { row: 0, col: 0 }
clearRenderPosition()
Remove the render override, returning to normal cursor display.
vim.cursor.clearRenderPosition(); // Cursor now renders at its actual position
Smooth Cursor Animation
Example implementation of a smear-cursor effect:
// Track cursor movement for animation let animationInProgress = false; function smoothMoveTo(targetRow: number, targetCol: number) { if (animationInProgress) return; animationInProgress = true; const start = vim.cursor.getPosition(); const duration = 150; // ms const startTime = Date.now(); function animate() { const elapsed = Date.now() - startTime; const progress = Math.min(elapsed / duration, 1); // Ease-out curve const eased = 1 - Math.pow(1 - progress, 3); const currentRow = Math.round( start.row + (targetRow - start.row) * eased ); const currentCol = Math.round( start.col + (targetCol - start.col) * eased ); vim.cursor.setRenderPosition(currentRow, currentCol); if (progress < 1) { setTimeout(animate, 16); // ~60fps } else { vim.cursor.clearRenderPosition(); animationInProgress = false; } } animate(); }
Use with vim.motion
Combine with vim.motion for animated movements:
vim.keymap.set('n', 'j', () => { const before = vim.cursor.getPosition(); vim.motion.down(); const after = vim.cursor.getPosition(); // Animate from old to new position smoothMoveTo(after.row, after.col); });
Cursor Trail Effect
Create a cursor trail by rendering multiple positions:
const trailPositions: Array<{row: number, col: number}> = []; const TRAIL_LENGTH = 5; vim.api.createAutocmd('CursorMoved', { callback: () => { const pos = vim.cursor.getPosition(); trailPositions.unshift({ ...pos }); if (trailPositions.length > TRAIL_LENGTH) { trailPositions.pop(); } // Render trail (implementation depends on layer API) } });
API Reference
| Function | Returns | Description |
|---|---|---|
getPosition() | { row: number, col: number } | Get logical cursor position (0-indexed) |
setRenderPosition(row, col) | void | Override visual cursor position |
clearRenderPosition() | void | Remove render override |
Notes
- Logical vs Visual:
getPosition()always returns the actual cursor position, regardless of render override - Performance: Render overrides trigger immediate re-rendering
- Cleanup: Always call
clearRenderPosition()when animation completes - Coordinates: All positions are 0-indexed
See Also
- vim.motion - Programmatic cursor movement
- vim.api - Window cursor functions
- Plugin Development - Build cursor animation plugins