(count: number, ctx: OperatorContext)
| 256 | * Execute join lines (J command). |
| 257 | */ |
| 258 | export function executeJoin(count: number, ctx: OperatorContext): void { |
| 259 | const text = ctx.text |
| 260 | const lines = text.split('\n') |
| 261 | const { line: currentLine } = ctx.cursor.getPosition() |
| 262 | |
| 263 | if (currentLine >= lines.length - 1) return |
| 264 | |
| 265 | const linesToJoin = Math.min(count, lines.length - currentLine - 1) |
| 266 | let joinedLine = lines[currentLine]! |
| 267 | const cursorPos = joinedLine.length |
| 268 | |
| 269 | for (let i = 1; i <= linesToJoin; i++) { |
| 270 | const nextLine = (lines[currentLine + i] ?? '').trimStart() |
| 271 | if (nextLine.length > 0) { |
| 272 | if (!joinedLine.endsWith(' ') && joinedLine.length > 0) { |
| 273 | joinedLine += ' ' |
| 274 | } |
| 275 | joinedLine += nextLine |
| 276 | } |
| 277 | } |
| 278 | |
| 279 | const newLines = [ |
| 280 | ...lines.slice(0, currentLine), |
| 281 | joinedLine, |
| 282 | ...lines.slice(currentLine + linesToJoin + 1), |
| 283 | ] |
| 284 | |
| 285 | const newText = newLines.join('\n') |
| 286 | ctx.setText(newText) |
| 287 | ctx.setOffset(getLineStartOffset(newLines, currentLine) + cursorPos) |
| 288 | ctx.recordChange({ type: 'join', count }) |
| 289 | } |
| 290 | |
| 291 | /** |
| 292 | * Execute paste (p/P command). |
no test coverage detected