()
| 1739 | } |
| 1740 | |
| 1741 | private handleForwardDelete(): void { |
| 1742 | this.exitHistoryBrowsing(); |
| 1743 | this.lastAction = null; |
| 1744 | |
| 1745 | const currentLine = this.state.lines[this.state.cursorLine] || ""; |
| 1746 | |
| 1747 | if (this.state.cursorCol < currentLine.length) { |
| 1748 | this.pushUndoSnapshot(); |
| 1749 | |
| 1750 | // Delete grapheme at cursor position (handles emojis, combining characters, etc.) |
| 1751 | const afterCursor = currentLine.slice(this.state.cursorCol); |
| 1752 | |
| 1753 | // Find the first grapheme at cursor |
| 1754 | const graphemes = [...this.segment(afterCursor, "grapheme")]; |
| 1755 | const firstGrapheme = graphemes[0]; |
| 1756 | const graphemeLength = firstGrapheme ? firstGrapheme.segment.length : 1; |
| 1757 | |
| 1758 | const before = currentLine.slice(0, this.state.cursorCol); |
| 1759 | const after = currentLine.slice(this.state.cursorCol + graphemeLength); |
| 1760 | this.state.lines[this.state.cursorLine] = before + after; |
| 1761 | } else if (this.state.cursorLine < this.state.lines.length - 1) { |
| 1762 | this.pushUndoSnapshot(); |
| 1763 | |
| 1764 | // At end of line - merge with next line |
| 1765 | const nextLine = this.state.lines[this.state.cursorLine + 1] || ""; |
| 1766 | this.state.lines[this.state.cursorLine] = currentLine + nextLine; |
| 1767 | this.state.lines.splice(this.state.cursorLine + 1, 1); |
| 1768 | } |
| 1769 | |
| 1770 | if (this.onChange) { |
| 1771 | this.onChange(this.getText()); |
| 1772 | } |
| 1773 | |
| 1774 | // Update or re-trigger autocomplete after forward delete |
| 1775 | if (this.autocompleteState) { |
| 1776 | this.updateAutocomplete(); |
| 1777 | } else { |
| 1778 | const currentLine = this.state.lines[this.state.cursorLine] || ""; |
| 1779 | const textBeforeCursor = currentLine.slice(0, this.state.cursorCol); |
| 1780 | // Slash command context |
| 1781 | if (this.isInSlashCommandContext(textBeforeCursor)) { |
| 1782 | this.tryTriggerAutocomplete(); |
| 1783 | } |
| 1784 | // Symbol-based completion context like @, #, or provider triggers |
| 1785 | else if (this.autocompleteTriggerPattern.test(textBeforeCursor)) { |
| 1786 | this.tryTriggerAutocomplete(); |
| 1787 | } |
| 1788 | } |
| 1789 | } |
| 1790 | |
| 1791 | /** |
| 1792 | * Build a mapping from visual lines to logical positions. |
no test coverage detected