MCPcopy Create free account
hub / github.com/MoonshotAI/kimi-code / moveCursor

Method moveCursor

packages/pi-tui/src/components/editor.ts:1856–1917  ·  view source on GitHub ↗
(deltaLine: number, deltaCol: number)

Source from the content-addressed store, hash-verified

1854 }
1855
1856 private moveCursor(deltaLine: number, deltaCol: number): void {
1857 this.lastAction = null;
1858 const visualLines = this.buildVisualLineMap(this.lastWidth);
1859 const currentVisualLine = this.findCurrentVisualLine(visualLines);
1860
1861 if (deltaLine !== 0) {
1862 const targetVisualLine = currentVisualLine + deltaLine;
1863
1864 if (targetVisualLine >= 0 && targetVisualLine < visualLines.length) {
1865 this.moveToVisualLine(visualLines, currentVisualLine, targetVisualLine);
1866 }
1867 }
1868
1869 if (deltaCol !== 0) {
1870 const currentLine = this.state.lines[this.state.cursorLine] || "";
1871
1872 if (deltaCol > 0) {
1873 // Moving right - move by one grapheme (handles emojis, combining characters, etc.)
1874 if (this.state.cursorCol < currentLine.length) {
1875 const afterCursor = currentLine.slice(this.state.cursorCol);
1876 const graphemes = [...this.segment(afterCursor, "grapheme")];
1877 const firstGrapheme = graphemes[0];
1878 this.setCursorCol(this.state.cursorCol + (firstGrapheme ? firstGrapheme.segment.length : 1));
1879 } else if (this.state.cursorLine < this.state.lines.length - 1) {
1880 // Wrap to start of next logical line
1881 this.state.cursorLine++;
1882 this.setCursorCol(0);
1883 } else {
1884 // At end of last line - can't move, but set preferredVisualCol for up/down navigation
1885 const currentVL = visualLines[currentVisualLine];
1886 if (currentVL) {
1887 this.preferredVisualCol = this.state.cursorCol - currentVL.startCol;
1888 }
1889 }
1890 } else {
1891 // Moving left - move by one grapheme (handles emojis, combining characters, etc.)
1892 if (this.state.cursorCol > 0) {
1893 const beforeCursor = currentLine.slice(0, this.state.cursorCol);
1894 const graphemes = [...this.segment(beforeCursor, "grapheme")];
1895 const lastGrapheme = graphemes[graphemes.length - 1];
1896 this.setCursorCol(this.state.cursorCol - (lastGrapheme ? lastGrapheme.segment.length : 1));
1897 } else if (this.state.cursorLine > 0) {
1898 // Wrap to end of previous logical line
1899 this.state.cursorLine--;
1900 const prevLine = this.state.lines[this.state.cursorLine] || "";
1901 this.setCursorCol(prevLine.length);
1902 }
1903 }
1904 }
1905
1906 // Keep an open autocomplete picker in sync with the new cursor
1907 // position: cursor movement changes the text before the cursor, so a
1908 // picker computed for the old position is stale. Re-query so it
1909 // refreshes — or closes when the new position yields no suggestions —
1910 // mirroring insertCharacter()/handleBackspace(). Without this, arrowing
1911 // left from `/cmd ` back into the command name leaves the argument
1912 // picker showing against a `/cmd` prefix (and a Tab there would
1913 // concatenate the stale suggestion onto the partial command name).

Callers 1

handleInputMethod · 0.95

Calls 6

buildVisualLineMapMethod · 0.95
findCurrentVisualLineMethod · 0.95
moveToVisualLineMethod · 0.95
segmentMethod · 0.95
setCursorColMethod · 0.95
updateAutocompleteMethod · 0.95

Tested by

no test coverage detected