diff --git a/src/shell/Wush.ts b/src/shell/Wush.ts index 3d01c8e..1282850 100644 --- a/src/shell/Wush.ts +++ b/src/shell/Wush.ts @@ -6,6 +6,9 @@ import type { EventBroadcaster } from '../utils/EventBroadcaster' import { Shell } from './Shell' export class Wush extends Shell { + private buffer: string[] = [] + private bufferPos: number = 0 + constructor(broadcaster: EventBroadcaster, terminal: Terminal) { super(broadcaster, terminal) } @@ -21,20 +24,63 @@ export class Wush extends Shell { this.terminal.Write('hi -> ') } + PushToBuffer(text: string) { + text.split('').forEach(char => { + this.buffer.splice(this.bufferPos, 0, char) + this.bufferPos++ + }) + + console.log(this.buffer) + } + + RemoveLastCharsFromBuffer(amount: number) { + this.buffer.splice(this.buffer.length - amount, amount) + this.bufferPos -= amount + + console.log(this.buffer) + } + + MoveBufferPos(index: number, absolute: boolean = false) { + this.bufferPos = Math.max(absolute ? index : this.bufferPos + index, 0) + } + + FlushBuffer() { + this.buffer = [] + this.bufferPos = 0 + } + + ExecuteBuffer() { + const args = this.buffer.join('').split(' ') + this.FlushBuffer() + + console.log(`Executing ${args[0]} with args '${args}'`) + } + HandleKeyInput(key: string, isCharacter: boolean) { - if (!isCharacter) + if (!isCharacter) { switch (key) { + case 'ArrowLeft': + this.terminal.MoveCursor(-1, 0) + this.MoveBufferPos(-1) + break + case 'ArrowRight': + this.terminal.MoveCursor(1, 0) + this.MoveBufferPos(1) + break case 'Backspace': this.terminal.RemoveCell() + this.RemoveLastCharsFromBuffer(1) this.terminal.MoveCursor(-1, 0) break case 'Enter': - this.terminal.MoveCursor(0, 4, { x: true, y: false }) + this.terminal.MoveCursor(0, 1, { x: true, y: false }) + this.ExecuteBuffer() this.Prompt() break } - else { - this.terminal.Write(key) + } else { + this.terminal.InsertCell(key) + this.PushToBuffer(key) this.terminal.MoveCursor(1, 0) } } diff --git a/src/styles/cursor.scss b/src/styles/cursor.scss index db44c03..17fccc1 100644 --- a/src/styles/cursor.scss +++ b/src/styles/cursor.scss @@ -7,4 +7,6 @@ height: 20px; position: absolute; background: colors.$terminal-white; + + transition: .2s cubic-bezier(0, 1, 0.3, 1); } diff --git a/src/styles/terminal.scss b/src/styles/terminal.scss index 7e53580..dbf5d71 100644 --- a/src/styles/terminal.scss +++ b/src/styles/terminal.scss @@ -24,7 +24,6 @@ } .line { - background: red; width: fit-content } } diff --git a/src/terminal/Terminal.ts b/src/terminal/Terminal.ts index e56c279..43935b0 100644 --- a/src/terminal/Terminal.ts +++ b/src/terminal/Terminal.ts @@ -19,9 +19,9 @@ export class Terminal { this.terminal = sqs('#terminal') this.cursor = sqs('#cursor') - this.SetCursorStyle('bar') - this.ResetCellSize() + + this.SetCursorStyle('bar') this.NewPage() } @@ -43,6 +43,12 @@ export class Terminal { paragraph.className = 'line' this.terminal.appendChild(paragraph) + paragraph.scrollIntoView({behavior: 'smooth'}) + } + + UpdateLines() { + const lines = new Array(...this.terminal.children) + lines.forEach((line, i) => line.id = `line-${i}`) } /** @@ -53,13 +59,10 @@ export class Terminal { } Write(text: string) { - let adjustment = 0 text.split('').forEach((char) => { - this.MoveCursor(adjustment, 0) - adjustment = 1 - this.SetCell(char) + this.MoveCursor(1, 0) }) } @@ -92,13 +95,23 @@ export class Terminal { sqs(selector).innerText = char[0] } - AppendCells(content: string) { - const paragraph = sqs(`#line-${this.cursorPosition.row}`) + UpdateCells() { + const cells = new Array(...sqs(`#line-${this.cursorPosition.row}`).children) + cells.forEach((cell, i) => cell.className = `cell-${i}`) + } - content.split('').forEach((char) => { - paragraph.textContent += char.replace(' ', '\u00A0') - this.MoveCursor(1, 0) - }) + InsertCell(char: string) { + const cell = document.createElement('span') + cell.className = `cell-${this.cursorPosition.col}` + cell.style.width = `${this.cellWidth}px` + cell.style.height = `${this.cellHeight}px` + cell.style.lineHeight = `${this.cellHeight}px` + + cell.innerText = char[0] + + sqs(`#line-${this.cursorPosition.row} .cell-${this.cursorPosition.col}`).insertAdjacentElement('beforebegin', cell) + + this.UpdateCells() } RemoveCell() { @@ -106,6 +119,8 @@ export class Terminal { sqs(`#line-${this.cursorPosition.row} .cell-${this.cursorPosition.col - 1}`).remove() } catch (_) { + } finally { + this.UpdateCells() } }